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 859998 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

WSH Panel Mod

Reply #50
v1.1.4 Released.

I play around the Editor Properties for a while. I've made up some cfgs for share.
1. Ruby Blue

Code: [Select]
# Name: Ruby Blue
# Ported by T.P Wang
# Generated by WSH Panel Mod
style.default=font:Bitstream Vera Sans Mono,size:10,fore:#ffffff,back:#121e31
style.comment=italics,fore:#428bdd
style.keyword=fore:#f8bb00
style.indentifier=$(style.default)
style.string=fore:#1dc116
style.number=fore:#eddd3d
style.operator=fore:#8aa6c1
style.linenumber=font:Courier New,size:8,fore:#2b91af
style.bracelight=bold,fore:#000000,back:#ffee62
style.bracebad=bold,fore:#ff0000
style.selection.fore=
style.selection.back=#38566f
style.selection.alpha=256
style.caret.fore=#ffffff
style.caret.width=1
style.caret.line.back=#253e5a
style.caret.line.back.alpha=256

2. Bright

Code: [Select]
# Name: Bright
# Ported by T.P Wang
# Ported from Komodo Edit
# Generated by WSH Panel Mod
style.default=font:Courier New,size:10,fore:#000000,back:#ffffff
style.comment=italics,fore:#666666
style.keyword=fore:#000085
style.indentifier=fore:#006600
style.string=fore:#996633
style.number=fore:#8b0000
style.operator=fore:#781f87
style.linenumber=font:Courier New,size:8,fore:#555555
style.bracelight=bold,fore:#ff0000,back:#ffff99
style.bracebad=bold,fore:#ff6666,back:#ffff66
style.selection.fore=
style.selection.back=
style.selection.alpha=256
style.caret.fore=
style.caret.width=1
style.caret.line.back=
style.caret.line.back.alpha=256

WSH Panel Mod

Reply #51
thank you T.P.Wang for this component
scite is my favourite editor, and if you are focused on extending scite in your project, maybe you can embed also an api files for jscript and vbscript for autocompletion and calltips

WSH Panel Mod

Reply #52
What should I put into txt variable to be able to display artist in such manner?
Code: [Select]
gr.GdiDrawText(txt, g_font, RGB(50,50,50), 0, 0, ww, wh, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

WSH Panel Mod

Reply #53
Quote
scite is my favourite editor, and if you are focused on extending scite in your project, maybe you can embed also an api files for jscript and vbscript for
autocompletion and calltips

Well, in fact, I didn't embed SciTE, it's Scintilla (However, SciTE is based on Scintilla editor component).
For me, SciTE is huge engough for a smal and simple component  , so I won't implemet too much features for editor in the near future.

Quote
What should I put into txt variable to be able to display artist in such manner?

Sample code:

Code: [Select]
// Create a title formating object
var tfo = fb.TitleFormat("%album artist%");
....
// Evaluate
var txt = tfo.Eval();
gr.GdiDrawText(txt, g_font, RGB(50,50,50), 0, 0, ww, wh, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

WSH Panel Mod

Reply #54
Isn't it possible to display "artist" without fb.TitleFormat but with MetaValue(idx,vidx) instead?
How would it look like?

WSH Panel Mod

Reply #55
@tedgo:
Here's the sample function:
Code: [Select]
// find index of meta name
function metaFind(info, name) {
    for (var i = 0; i < info.MetaCount; i++) {
        if (info.MetaName(i).toLowerCase() == name.toLowerCase())
            return i;
    }
   
    return -1;
}

// return all values in an array
function metaGet(info, name) {
    var i = metaFind(info, name);
    var arr = []
   
    if (i != -1) {
        for (var j = 0; j < info.MetaValueCount(i); j++) {
            arr.push(info.MetaValue(i, j));
        }
    }
   
    return arr;
}

And sample usage:
Code: [Select]
 ...
 var info = metadb.GetFileInfo();
 // Print to console, join all array elements together, and separated by ","
 fb.trace(metaGet(info).join(','));

WSH Panel Mod

Reply #56
@T.P Wang
Thanks again (and again and again)

WSH Panel Mod

Reply #57
T.P. Wang, I'm trying to do a reflection type effect for album art, but I'm not sure how. I'm trying

Code: [Select]
gr.DrawImage(g_img, 0, 0, ww, ww*g_img.Height/g_img.Width, 0, 0, g_img.Width, g_img.Height);
gr.DrawImage(g_img.Rotate(180), 0, ww*g_img.Height/g_img.Width, ww, ww*g_img.Height/g_img.Width, 0, 0, g_img.Width, g_img.Height);

But it doesn't work, the second image doesn't show up. It's not giving an error though. I tried RotateFlip() as well but it gave an error. What am I doing wrong?

WSH Panel Mod

Reply #58
@TomBarlow:
The Rotate() method in IGdiBitmap interface is TOTALLY BROKEN. I'll remove it later.
The "Rotate" should be add to DrawImage() as a prameter.

RotateFlip() apply current image only, that means, you should clone the image, and apply RotateFlip() to the new image, sample code
Code: [Select]
function get_album_art(metadb) {
if (metadb)
// Get front cover
return utils.GetAlbumArt(metadb.RawPath, 0);
}

var g_img = null;
var g_rotate_img = null;
var ww;

on_playback_new_track(fb.GetNowPlaying());

function on_paint(gr) {
if (g_img) {
gr.SetInterpolationMode(7); // Highest quality and also slowest
gr.DrawImage(g_img, 0, 0, 200, 200, 0, 0, g_img.Width, g_img.Height);
g_rotate_img && gr.DrawImage(g_rotate_img, 0, 200, 200, 200, 0, 0, g_rotate_img.Width, g_rotate_img.Height);
}
}

function on_size() {
ww = window.Width;
}

function on_playback_new_track(metadb) {
if (!metadb) return;

g_img = get_album_art(metadb);
g_rotate_img = g_img.Clone(0, 0, g_img.Width, g_img.Height);
g_rotate_img.RotateFlip(2); // 180
window.Repaint();
}


WSH Panel Mod

Reply #59
Cool, thanks very much, it works nicely.

WSH Panel Mod

Reply #60
I just want to know if there are already shared configs for this plugin in the upload section? I habe no Idea of jscript. So if some of you would share their configs I would be grateful.

WSH Panel Mod

Reply #61
Why don't you look at my posts above. I posted four "configs" :
  • Volume bar
  • Rating
  • Seekbar
  • Stop after current (with changing state) button

WSH Panel Mod

Reply #62
For those who are interested, here is a new version of my components :

Volume bar:Don't forget to place this image in your foobar\images directory : 
Code: [Select]
function RGB(r,g,b){ return (0xff000000|(r<<16)|(g<<8)|(b)); }
var g_font = gdi.Font("Tahoma", 12, 0);
var g_drag = 0;
var ww;
var hofset = 10;
var wh = 5;
var ih=16; var iw=9;
var vofset;
var grad;

function on_paint(gr){

    grad = Math.pow((100+fb.Volume)/100,2);
    vofset = (window.Height-wh)/2;
    ww = window.Width - 2*hofset;

   

    gr.FillGradRect(hofset+1,vofset, ww*grad, wh, 90, (grad<=0)  ? RGB(32,32,92) : RGB(32+128*grad,164*(1-grad),32*(1-grad)), RGB(255,255,255));
    gr.FillGradRect(hofset+ww*grad+1,vofset, ww*(1-grad)-1,wh, 90, RGB(92,92,92), RGB(255,255,255));
   
    gr.DrawRect(hofset,vofset, ww, wh+1, 1, RGB(192,192,192));
    img = gdi.image(fb.FoobarPath + "Images\\Volume.png");
    gr.DrawImage(img, hofset+ww*grad-iw/2, (window.Height-ih)/2, iw, ih, 0, 0,iw, ih);
   
   
   
}
function on_mouse_lbtn_down(x,y){
    g_drag = 1;
}
function on_mouse_lbtn_up(x,y){
    on_mouse_move(x,y);
    g_drag = 0;
}
function on_mouse_move(x,y){
    if(g_drag){
        var v = (x-hofset)/ww;
        v = (v<0) ? 0 : (v<1) ? v : 1;
        v = 100 * (Math.pow(v,1/2) - 1);
        fb.Volume = v;
    }   
}
function on_mouse_wheel(delta){
    if(delta>0)
        fb.VolumeUp();
    else
        fb.VolumeDown();
}
function on_volume_change(val){
    window.Repaint();
}
function on_playback_time(time){
window.Repaint();
}
//EOF
SeekbarDon't forget to place these images in your foobar\images directory :   
Code: [Select]
function RGB(r,g,b){ return (0xff000000|(r<<16)|(g<<8)|(b)); }
var g_font = gdi.Font("Tahoma", 12, 0);
var g_drag = 0;
//var ww = 340;
var hofset = 12;
var is = 14;
var wh = 4;
var vofset;
var length;
var grad;
var col = RGB(24,24,92);
var img = gdi.image(fb.FoobarPath + "Images\\Cursor.png");

function on_paint(gr){
    vofset = (window.Height-wh)/2;
    ww = window.Width - 2*hofset;
//    fb.trace("ww="+ww);
    length = fb.PlaybackLength;
    grad = 0;
    if (length > 0)  grad = fb.PlaybackTime/fb.PlaybackLength;

    gr.FillGradRect(hofset+1,vofset, ww*grad, wh, 90, col, RGB(255,255,255));
   
    gr.FillGradRect(hofset+ww*grad+1,vofset, ww*(1-grad)-1,wh, 90, RGB(92,92,92), RGB(255,255,255));
    gr.DrawRect(hofset,vofset, ww, wh+1, 1, RGB(192,192,192));
   
    gr.DrawImage(img, hofset+ww*grad-is/2, (window.Height-is)/2, is, is, 0, 0,is, is);




   
   
   
}
function on_mouse_lbtn_down(x,y){
    g_drag = 1;
}
function on_mouse_lbtn_up(x,y){
    on_mouse_move(x,y);
    g_drag = 0;
}
function on_mouse_move(x,y){
    if(g_drag){
        var v = (x-hofset)/ww;
        v = (v<0) ? 0 : (v<1) ? v : 1;
        fb.PlaybackTime = fb.PlaybackLength * v;

           
           
    }
   
}
function on_mouse_wheel(delta){
    if(delta>0)
        fb.PlaybackTime = fb.PlaybackTime + delta;
    else
        fb.PlaybackTime = fb.PlaybackTime + delta;
}
function on_playback_new_track(info){
    window.Repaint();
}
function on_playback_stop(){
    img = gdi.image(fb.FoobarPath + "Images\\Cursor" +".png");
    window.Repaint();
}
function on_playback_seek(time){
    window.Repaint();
}

function on_playback_time(time){
window.Repaint();
}
function on_playback_pause(state) {
    img = gdi.image(fb.FoobarPath + "Images\\Cursor" + (state ? "-paused" :  "") +".png");
    col = state ?  RGB(24,24,24) : RGB(24,24,92);
    window.Repaint();
    }

@TP Wang: Could it be possible to have a function for displayong tooltips ?
[blockquote][blockquote]Many thanks.
[/blockquote][/blockquote]

WSH Panel Mod

Reply #63
Thank you very much NEMO7538 for your code examples. Could you please post a rating code, or what must be changed in the original code, for rating the currently playing file, and not the selected file.

WSH Panel Mod

Reply #64
Put the code of on_item_focus_change() in on_playback_new_track(metadb)
then :
  • suppress the on_item_focus_change() section
  • replace this line g_metadb = fb.GetFocusItem(); by g_metadb = metadb;

Not tested but it should work.

WSH Panel Mod

Reply #65
I thought I'd share my volume control. It has a logarithmic scale, which I think is more natural sounding than linear- I think it's what the DUI and CUI volume sliders use anyway (I think the DUI one has a slightly different scaling). Also, mine is vertical.

I also came up with an HSV function- although it's a lot bigger than your method Nemo!

Code: [Select]
function HSV(h,s,v)
{
h=Math.abs(h%360);
s=(s<0)?0:(s>100)?100:s;
v=(v<0)?0:(v>100)?100:v;
s=s/100;
v=v/100;
h_i=Math.floor(h/60)%6;
f=h/60-Math.floor(h/60);
p=v*(1-s);
q=v*(1-f*s);
t=v*(1-(1-f)*s);
switch(h_i)
{
case 0:
return (0xff000000|(0xff*v<<16)|(0xff*t<<8)|(0xff*p));
break;
case 1:
return (0xff000000|(0xff*q<<16)|(0xff*v<<8)|(0xff*p));
break;
case 2:
return (0xff000000|(0xff*p<<16)|(0xff*v<<8)|(0xff*t));
break;
case 3:
return (0xff000000|(0xff*p<<16)|(0xff*q<<8)|(0xff*v));
break;
case 4:
return (0xff000000|(0xff*t<<16)|(0xff*p<<8)|(0xff*v));
break;
case 5:
return (0xff000000|(0xff*v<<16)|(0xff*p<<8)|(0xff*q));
break;
}
}

var g_drag = 0;
var txt;
var wid;
var a = 25;
var b = 15;
var g_font = gdi.Font("Calibri", 10, 1);

function on_paint(gr){
gr.SetTextRenderingHint(5);
var ww = window.Width;
var wh = window.Height;
var pos = wh * Math.exp(fb.Volume/a);
gr.FillSolidRect(0,0,ww,wh,0xfffcfcfc);
gr.FillSolidRect(0,0,6,wh,HSV(240+Math.exp(fb.Volume/b)*120,30,100));
gr.FillSolidRect(2,wh-pos+2,2,pos-4,HSV(0,0,50*(1-Math.exp(fb.Volume/b))));
txt = fb.Volume>-100?Math.ceil(10*fb.Volume)/10 + " dB":"mute";
wid = gr.CalcTextWidth(txt,g_font);
gr.DrawString(txt, g_font, HSV(0,0,70), 6, (pos>(wid+4))?wh-pos+3:wh-wid-1, ww-6, wh,0x00000002);
gr.DrawString(txt, g_font, HSV(0,0,15), 6, (pos>(wid+4))?wh-pos+2:wh-wid-2, ww-6, wh,0x00000002);
}

function on_mouse_lbtn_down(x,y){
g_drag = 1;
on_mouse_move(x,y);
}

function on_mouse_lbtn_up(x,y){
g_drag = 0;
}

function on_mouse_move(x,y){
if(g_drag){
var v = 1-y/window.Height;
v = (v<Math.exp(-100/a)) ? Math.exp(-100/a) : (v<1) ? v : 1;
fb.Volume = a*Math.log(v);
}
}

function on_mouse_wheel(delta){
fb.Volume=fb.Volume+delta*Math.exp(-fb.Volume/a);
}

function on_volume_change(val){
window.Repaint();
}

WSH Panel Mod

Reply #66
Put the code of on_item_focus_change() in on_playback_new_track(metadb)
then :
  • suppress the on_item_focus_change() section
  • replace this line g_metadb = fb.GetFocusItem(); by g_metadb = metadb;

Not tested but it should work.


Thanks, I'll try.

WSH Panel Mod

Reply #67
v1.1.5 Released.

Samples also updated (Add new Tooltip sample)

@NEMO7538:
You can add tooltips now.

@TomBarlow:
I think this is more flexible for ears  :

Code: [Select]
// 0 <= p <= 1
// return a value value: -100 <= vol <= 0
function pos2vol(p){
     return (50*Math.log(0.99*p+0.01)/Math.LN10);
};

function vol2pos(v){
     return (Math.round(((Math.pow(10,v/50)-0.01)/0.99)));
};

WSH Panel Mod

Reply #68
Thanks TP Wang
Regarding the volume control, I personally use :
v = Math.pow((100+fb.Volume)/100,2); and
fb.Volume = 100 * (Math.pow(v,1/2) - 1);

WSH Panel Mod

Reply #69
I didn't see anything in the folder that comes with the componant explaining the format this uses.
I want to change the seekbar and volumebar and tested samples from this thread, but, call me stupid, what format do I save the code too in txt file?
XML?

Thank you

I had a previous theme that used wsh panel but some foobar2000 update awhile back stopped it somehow or a crash...anyhow, I dont remember what it was he used it for in the theme nor the theme itself, but am looking to play with this componant again.

Is there a detailed how to on componants homepage, if there even is a homepage?

WSH Panel Mod

Reply #70
@Ironwalker:
You should learn about JScript (Preferred) or VBScript.
Once you learned (even a little), you should be able to know the Instructions in binary archive and Samples in samples archive.

WSH Panel Mod

Reply #71
Ironwalker- The (default) language used is JScript (you can also use VBScript). It can be saved as .js or .txt, although you don't need to save the examples in this thread- just copy and paste them into the editor. Although JScript is not really JavaScript, it uses the same syntax, you can learn it here or here. The important different is, JScript doesn't have any of the HTML DOM objects, but it does have foobar related objects instead, with their own properties and methods, and its own callback functions, which are detailed in the interfaces and callbacks txt files. The console (View>Console) is very useful when writing a script, if you get a script error it should tell you where you're going wrong.


T.P. Wang- thanks for the latest version, tooltips are a great addition. I have got stuck again with something- I can't get on_playback_dynamic_info_track to work with stream info (artist/title) e.g Woxy radio- I'm trying:

function on_playback_dynamic_info_track()
{
   g_focus_metadb = fb.GetNowPlaying();
   window.Repaint();
}

With g_focus_metadb being used later in EvalWithMetadb(g_focus_metadb), but it's not working. A similar thing works with on_item_focus_change and gb.GetFocusItem().

Another small q... is it/would it be possible to perform a time delay- like setTimeout(window.Repaint(),500)- it would be nice to redraw a seekbar more than once per second, just to make it look smoother

Thanks!

WSH Panel Mod

Reply #72
I added the following line to my code:
Code: [Select]
    gr.DrawString(fb.TitleFormat("%playback_time%").Eval(),g_font_b,RGB(0,0,0),32,30,54,16,DT_CENTER | DT_TOP | DT_SINGLELINE);


But the playbacktime doesn't go on. I know I must add something that tells the panel to repaint the time.

Can someone give me a hint?


WSH Panel Mod

Reply #74
@TomBarlow:
There's no need to get metadb handle, and you can only access dynamic info thru Eval() method in WSH Panel Mod.
So, what you really need is a repaint request to draw dynamic info, there is an example (pseudo code):
Code: [Select]
function on_playback_dynamic_info_track() {
    window.Repaint();
}

function on_paint(gr) {
    var text = g_tfo.Eval();
    gr.DrawString(text, ....);
}


PS:
The Eval() method is applied to now playing metadb handle, implicitly.

@Spirit_of_the_ocean:
Add a callback function, and send a repaint request:
Code: [Select]
function on_playback_time(time) {
    window.Repaint();
}


PS: These Flags start with DT_* is applied to GdiDrawString() method only, if you wanto use them in DrawString(), see Flags.txt for more details. (You can also check out BoxBlur.txt in Samples, just have a look at the flags usage, don't care about other methods except DrawString());