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 815569 times) previous topic - next topic
0 Members and 2 Guests are viewing this topic.

WSH Panel Mod

Reply #300
@tedgo & tombarlow

  thanks so much for your help, defining the variables in the onpaint function did the trick.  i had tried before defining them as globals (at the beginning of the script,) and then redefining the in the onplaybackchange function, but for some reason it wasn't working for me.  ah - noticed the extra comma too, thanks!  thanks to tom also for the reply to the rotation issue - i've got it working nicely now, and found a workaround defining the center of the rotation.  since the rotate attribute rotates around the center of the image by default, you just have to resize the image so that the point you want to be the center of rotation is actually the center of the image...  hopefully before long i can share the config i'm working on.
  any ideas about more documentation on this component?  i'm still hacking my way through, but i can't fully figure out the files include with the download...

thanks again
  jk
i'er heights

WSH Panel Mod

Reply #301
Its for sure a silly question, but can anybody tell me how i could make a tooltip that changes with the state of the button?

I want to make a stop-after-current button that shows "Stop-after-current" in tooltip, but "Reset stop-after-current" when Stop-after-current is active.

I tried a variable like this:
var sac_tooltip = (fb.StopAfterCurrent) ? "Reset stop-after-current" : "Stop-after-current";
and repeated it in on_playlist_stop_after_current_changed but had no luck.
Any ideas?

This is the script (cut down to the stop-after-current button) i want to insert the "dynamic" tooltip:
Code: [Select]
var imgPath = fb.FoobarPath + "DarkOne\\Buttons\\";
var sac_on = {normal: imgPath + "SACon.png", hover: imgPath + "SACMH.png"};
var sac_off = {normal: imgPath + "SACoff.png", hover: imgPath + "SACMH.png"};
var sac_tooltip = (fb.StopAfterCurrent) ? "Reset stop-after-current" : "Stop-after-current";

var g_tooltip = window.CreateTooltip();
var Buttons = {};
var g_down = false;
var btn_down;

var ButtonStates = {
normal: 0,
hover: 1,
down: 2
}

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 Button(x, y, w, h, img_src, func, tiptext)  {
this.left = x;
this.top = y;
this.w = w;
this.h = h;
this.right = x + w;
this.bottom = y + h;
this.func = func;
this.tiptext = tiptext;
this.state = ButtonStates.normal;
this.img_normal = img_src && img_src.normal ? gdi.Image(img_src.normal) : null;
this.img_hover = img_src && img_src.hover ? gdi.Image(img_src.hover) : this.img_normal;
this.img_down = img_src && img_src.down ? gdi.Image(img_src.down) : this.img_hover;
this.img = this.img_normal;

this.alterImage = function(img_src) {
this.img_normal = img_src && img_src.normal ? gdi.Image(img_src.normal) : null;
this.img_hover = img_src && img_src.hover ? gdi.Image(img_src.hover) : this.img_normal;
this.img_down = img_src && img_src.down ? gdi.Image(img_src.down) : this.img_hover;
this.changeState(this.state);
}

this.traceMouse = function (x, y) {
var b = (this.left < x) && (x < this.right) && (this.top < y) && (y < this.bottom);
if (b)
g_down ? this.changeState(ButtonStates.down) : this.changeState(ButtonStates.hover);
else
this.changeState(ButtonStates.normal);
return b;
}


this.changeState = function (newstate) {
if (newstate != this.state)
window.RepaintRect(this.left, this.top, this.w, this.h);
this.state = newstate;
switch (this.state)
{
case ButtonStates.normal:
this.img = this.img_normal;
break;

case ButtonStates.hover:
this.img = this.img_hover;
break;

case ButtonStates.down:
this.img = this.img_down;
break;

default:
this.img = null;
}
}

this.draw = function (gr) {
this.img && gr.DrawImage(this.img, this.left, this.top, this.w, this.h, 0, 0, this.w, this.h);
}

this.repaint = function() {
window.RepaintRect(this.left, this.top, this.w, this.h);
}

this.onClick = function () {
this.func && this.func(x,y);
}
this.onMouseIn = function() {
g_tooltip.Text = this.tiptext;
g_tooltip.Activate();
}

this.onMouseOut = function() {
g_tooltip.Deactivate();
}
}

function buttonsDraw(gr) {
for (i in Buttons) {
Buttons[i].draw(gr);
}
}

function buttonsTraceMouse(x, y) {
var btn = null;

for (i in Buttons) {
if (Buttons[i].traceMouse(x, y) && !btn)
btn = Buttons[i];
}

return btn;
}

cur_btn = null;

function on_mouse_move(x, y) {
var btn = buttonsTraceMouse(x, y);

if (btn != cur_btn) {
cur_btn && cur_btn.onMouseOut();
btn && btn.onMouseIn();
}

cur_btn = btn;
}

function on_mouse_lbtn_down(x, y) {
g_down = true;
btn_down = cur_btn;

if (cur_btn)
cur_btn.changeState(ButtonStates.down);
}

function on_mouse_lbtn_up(x, y) {
if (cur_btn) {
cur_btn.changeState(ButtonStates.hover);
if( btn_down == cur_btn )
cur_btn.onClick(x, y);
}

g_down = false;
}

function on_paint(gr) {
gr.FillGradRect(0, 0, window.Width, window.Height, 90, RGB(38, 60, 76), RGB(31, 50, 63));
buttonsDraw(gr);
}

function on_mouse_leave() {
if (cur_btn)
cur_btn.changeState(ButtonStates.normal);
}

function genSACImageSrc() {
return (fb.StopAfterCurrent) ? sac_on : sac_off;
}

Buttons["SAC"] = new Button(0, 0, 13, 11, genSACImageSrc(), function () {fb.RunMainMenuCommand("Playback/Stop After Current");}, sac_tooltip);

function on_playlist_stop_after_current_changed(state) {
        sac_tooltip = (fb.StopAfterCurrent) ? "Reset stop-after-current" : "Stop-after-current";

Buttons.SAC.alterImage(genSACImageSrc());
Buttons.SAC.repaint();
}

WSH Panel Mod

Reply #302
You are passing sac_tooltip as a parameter to the Button object here:
Quote
Buttons["SAC"] = new Button(0, 0, 13, 11, genSACImageSrc(), function () {fb.RunMainMenuCommand("Playback/Stop After Current");}, sac_tooltip);


So the Button object doesn't know, when the value of sac_tooltip changes. Try:
Quote
function on_playlist_stop_after_current_changed(state) {
//sac_tooltip = (fb.StopAfterCurrent) ? "Reset stop-after-current" : "Stop-after-current";
Buttons.SAC.tiptext = (fb.StopAfterCurrent) ? "Reset stop-after-current" : "Stop-after-current";

Buttons.SAC.alterImage(genSACImageSrc());
Buttons.SAC.repaint();
}

WSH Panel Mod

Reply #303
Ah, thank you

WSH Panel Mod

Reply #304
Beta 9 uploaded.
No new features, only bug fixes.


WSH Panel Mod

Reply #306
a quick question...
  i believe there is a way to force a window resize from within the wsh panel, but i'm not sure how to do it...  want to place a "big window/small window" button in the panel to switch from the full screen layout to a sidebar layout - can anyone point me in the right direction?  also still interested in more complete documentation on the functions/methods/callbacks for wsh panel...  the files that came with the .dll detail changes, but don't provide a complete list, and i admit i'm a bit lost at times looking through them! 

@ t.p wang - please don't take my confusion over the .txt files the wrong way!  this component is AWESOME, but i'm not very familiar with jscript (i'm reading up all i can online) and i think i may be missing some critical information...

thanks - j
i'er heights

 

WSH Panel Mod

Reply #307
panel stack splitter can resize the foobar window. i'm not sure if WSH panel can.



WSH Panel Mod

Reply #309
you can create a button to do it like this...

Code: [Select]
$imagebutton(x pos, y pos, width, height, path to image, path to hot image,WINDOWSIZE:1024:768;REFRESH)


TIP: resize foobar manually to the size you want. then use alt-print screen to copy the active window to the clipboard. now open mspaint and paste. now look at the image attributes and this will be the size you'll want to use in the WINDOWSIZE option above.


WSH Panel Mod

Reply #311
hey all -
  thought after so many questions i'd share the wsh panel i'm working on.  it displays the album art as a "picture disc" on a turntable.  the playback buttons are on the turntable (fairly self-evidently,) and there are a couple of buttons (for the album list and menu) that won't do anything unless you set them up in dockable panels - but whatever.  the pitch shifter functions as the volume (still not completely satisfied with the volume curve, working on it...) and the tone arm functions as the seek bar.  you'll need these images...  put the "jkTurntable" folder in .../foobar2000/images.  here's the code - thanks to tedgo, tom barlow, falstaff, and whoever wrote the get_album_art sample (!) for the help with the scripting.
Code: [Select]
//VARIABLES=========================
var imgdir = fb.FoobarPath + "images\\jkTurntable\\";
//turntable
var tth = 0;
var ttv = 0;
var ww = window.Width;
var wh = window.Height;
var ang = 0;
var arm = gdi.Image(imgdir + "arm.png");
var tt = gdi.Image(imgdir + "techblank.png");
var ttstop = gdi.Image(imgdir + "tech.png");
var disc = gdi.Image(imgdir + "disc.png");
var nocover = gdi.Image(imgdir + "nocover.png");
//volume
var v_drag = 0;
var volx = 547 + tth;
var voly = 245 + ttv;
var volxmax = volx + 26;
var volymin = 250 + ttv;
var volymax = 400 + ttv;
var travel = 22;
//progress
var px = 360 + tth;
var py = 270 + tth;
var pw = 100;
var ph = 130;
var p_drag = 0;
var pxmin = px - pw;
var pymax = py + ph;

//album art
AlbumArtId = {
front: 0,
back: 1,
disc: 2,
icon: 3
};
var cover = null;

//BUTTON OBJECT=======================================
button = function () {
this._attrb = {};

this.create = function (path_normal, path_hover, path_down) {
  this._attrb.normal = gdi.Image(path_normal);
  this._attrb.hover = gdi.Image(path_hover);
  this._attrb.down= gdi.Image(path_down);
  if (typeof this._attrb.x == "undefined") this._attrb.x= 0;
  if (typeof this._attrb.y == "undefined") this._attrb.y= 0;
  this._attrb.w = this._attrb.normal.Width;
  this._attrb.h= this._attrb.normal.Height;
  if (typeof this._attrb.state == "undefined") this._attrb.state=0;
}

this.draw = function (gr, bx, by, alpha) {
  var image;
  this._attrb.x = bx;
  this._attrb.y = by;
  switch(this._attrb.state)
 {
    case 0:
      image = this._attrb.normal;
      break;
    case 1:
      image = this._attrb.hover;
      break;
    case 2:
      image = this._attrb.down;
      break;
  }
  gr.DrawImage(image, bx, by, this._attrb.w, this._attrb.h, 0, 0, this._attrb.w, this._attrb.h, 0, alpha);
}

this.checkstate = function (action, x, y) {
  switch(action)
  {
    case "down":
      if (x>this._attrb.x && xthis._attrb.y && y
      {
        this._attrb.state=2;
window.Repaint();
      } else if (this._attrb.state==2){
        this._attrb.state=0;     
        window.Repaint();
      }
      break;
    case "move":
      if (x>this._attrb.x && xthis._attrb.y && y
      {
        this._attrb.state=1;
window.Repaint();
      } else if (this._attrb.state==1){
        this._attrb.state=0;
        window.Repaint();   
      }
      break;
    case "up":
      if (x>this._attrb.x && xthis._attrb.y && y
      {
this._attrb.state=1;
      } else {
this._attrb.state=0;
      }
      break;
  }
  return this._attrb.state;
}

}

//BUTTON VARIABLES=====================================
var btn01 = new button;
var btn02 = new button;
var btn03 = new button;
var btn04 = new button;
var btn05 = new button;
var btn06 = new button;
var btn07 = new button;
var btn08 = new button;

var btndir = imgdir +"buttons\\";
var ButtonStates = {normal: 0,hover: 1,down: 2};
var ww;
var wh;

//PAINT===============================================
function on_paint(gr)
{
var coversize = 405
var slider = gdi.image(imgdir + "volslider.png");
var volume = fb.Volume;
var pos = 135 * ((100+volume)/100);
var sliderhz = (pos * -1) + 135;

gr.DrawImage(nocover, 33 + tth, 31 + ttv, coversize, coversize, 0, 0, nocover.Width, nocover.Height);
cover && gr.DrawImage(cover, 33+ tth, 31 + ttv, coversize, coversize, 0, 0, cover.Width, cover.Height);
gr.DrawImage(disc, 33 + tth, 31 + ttv, coversize, coversize, 0, 0, disc.Width, disc.Height);

if(fb.IsPlaying || fb.IsPaused){
gr.DrawImage(tt, tth, ttv, tt.Width, tt.Height, 0, 0, tt.Width, tt.Height);
gr.DrawImage(arm,203 + tth, -193 + ttv, arm.Width, arm.Height, 0, 0, arm.Width, arm.Height,angle = ang)};
else{
gr.DrawImage(ttstop,tth,ttv,ttstop.Width,ttstop.Height,0,0,ttstop.Width,ttstop.Height)};

gr.Drawimage(slider,volx,voly + sliderhz,slider.Width,slider.Height,0,0,slider.Width,slider.Height);

//buttons
//menu
btn01.draw(gr,tth + 545,ttv + 435,255);
//album list
btn02.draw(gr,tth + 20,ttv + 20,255);
//search
btn03.draw(gr,tth + 514,ttv + 435,255);
//stop
btn04.draw(gr,tth + 76,ttv + 441,255);
//prev
btn05.draw(gr,tth + 109,ttv + 441,255);
//playpause
btn06.draw(gr,tth + 538,ttv + 108,255);
//next
btn07.draw(gr,tth + 13,ttv + 409,255);
//playback order
btn08.draw(gr,tth + 13,ttv + 357,255);
}

//SIZE==(create buttons)===================================
function on_size() {
ww = window.Width;
wh = window.Height;

btn01.create(btndir+"menu.png", btndir+"menu1.png", btndir+"menu.png");
btn02.create(btndir+"albumlist.png", btndir+"albumlist1.png", btndir+"albumlist.png");
btn03.create(btndir+"search.png", btndir+"search1.png", btndir+"search.png");
btn04.create(btndir+"stop.png", btndir+"stop1.png", btndir+"stop.png");
btn05.create(btndir+"prev.png", btndir+"prev1.png", btndir+"prev.png");
btn06.create(btndir+"playpause.png", btndir+"playpause1.png", btndir+"playpause.png");
btn07.create(btndir+"next.png", btndir+"next1.png", btndir+"next.png");
btn08.create(btndir+"shuffle.png", btndir+"shuffle1.png", btndir+"shuffle.png");

}

//TIME================================================
function on_playback_time(time)
{
    ang = travel * fb.PlaybackTime / fb.PlaybackLength;
   
    if(fb.IsPlaying && !fb.IsPaused) {
btn06.create(btndir+"playpause.png", btndir+"playpause1.png", btndir+"playpause.png");
}
else {
btn06.create(btndir+"playpause.png", btndir+"playpause1.png", btndir+"playpause.png");
}
window.Repaint();
}

//MOUSE LBTN DOWN=====================================
function on_mouse_lbtn_down(x,y){

if(x > volx && x < volxmax && y > volymin && y < volymax){v_drag = 1};

if(x > pxmin && x < px && y > py && y < pymax){p_drag = 1};

//buttons
var state;

if (btn01.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("View/Dockable Panels/Activate/1 - Menu");
}

if (btn02.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("View/Dockable Panels/Activate/2 - Album list");
}

if (btn03.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("Library/Search");
}

if (btn04.checkstate("down",x,y)==ButtonStates.down) {
fb.Stop();
}

if (btn05.checkstate("down",x,y)==ButtonStates.down) {
fb.Prev();
}

if (btn06.checkstate("down",x,y)==ButtonStates.down) {
fb.PlayOrPause();
}

if (btn07.checkstate("down",x,y)==ButtonStates.down) {
fb.Next();
}

if (btn08.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("View/Dockable Panels/Activate/3 - Playback order");
}

}

//MOUSE LBTN UP========================================
function on_mouse_lbtn_up(x,y){
on_mouse_move(x,y);
v_drag = 0;

p_drag = 0;

btn01.checkstate("up",x,y);
btn02.checkstate("up",x,y);
btn03.checkstate("up",x,y);
btn04.checkstate("up",x,y);
btn05.checkstate("up",x,y);
btn06.checkstate("up",x,y);
btn07.checkstate("up",x,y);
btn08.checkstate("up",x,y);
window.Repaint();
}

//MOUSE MOVE==========================================
function on_mouse_move(x,y){
if(v_drag){
var v =(y - (voly+115)) /  -100;
v = (v<0) ? 0 : (v<1) ? v : 1;
v = -100 * (1-v);
if(fb.Volume != v)
fb.Volume = v;
}

if(p_drag){
var pxx = (x-px) + pw
var v = pxx/pw;
v = (v<0) ? 0 : (v<1) ? v : 1;
fb.PlaybackTime = fb.PlaybackLength - (fb.PlaybackLength * v);
}

btn01.checkstate("move",x,y);
btn02.checkstate("move",x,y);
btn03.checkstate("move",x,y);
btn04.checkstate("move",x,y);
btn05.checkstate("move",x,y);
btn06.checkstate("move",x,y);
btn07.checkstate("move",x,y);
btn08.checkstate("move",x,y);
}

//MOUSE LEAVE==========================================
function on_mouse_leave() {
btn01.checkstate("up",0,0);
btn02.checkstate("up",0,0);
btn03.checkstate("up",0,0);
btn04.checkstate("up",0,0);
btn05.checkstate("up",0,0);
btn06.checkstate("up",0,0);
btn07.checkstate("up",0,0);
btn08.checkstate("up",0,0);

window.Repaint();
}

//MOUSE WHEEL=========================================
function on_mouse_wheel(delta){
if(delta>0)
fb.VolumeUp();
else
fb.VolumeDown();
}

//VOLUME CHANGE=======================================
function on_volume_change(val){
window.Repaint();
}

//SEEK================================================
function on_playback_seek(time){
window.Repaint();
}

//ALBUM ART============================================
function get_album_art(metadb) {
if (metadb)
// Get front cover
return utils.GetAlbumArt(metadb.RawPath, AlbumArtId.front);
}
cover = get_album_art(fb.GetNowPlaying());

//NEW TRACK===========================================
function on_playback_new_track(metadb) {
cover = get_album_art(metadb);
window.Repaint();
}

//EOF
i'er heights

WSH Panel Mod

Reply #312
not sure what happened with the codebox, but it seems like the code there crashes wsh.  don't know how i manage to screw up all my posts, but there ya go.  included in the images folder is a .txt of the wsh script which does work (for me at least....)  sorry.
i'er heights

WSH Panel Mod

Reply #313
works fine here. I've added a cover rotation

not perfect but it gives you the way to do it

Code: [Select]
//VARIABLES=========================
var imgdir = fb.FoobarPath + "images\\jkTurntable\\";
//turntable
var tth = 0;
var ttv = 0;
var ww = window.Width;
var wh = window.Height;
var ang = 0;
var arm = gdi.Image(imgdir + "arm.png");
var tt = gdi.Image(imgdir + "techblank.png");
var ttstop = gdi.Image(imgdir + "tech.png");
var disc = gdi.Image(imgdir + "disc.png");
var nocover = gdi.Image(imgdir + "nocover.png");
//volume
var v_drag = 0;
var volx = 547 + tth;
var voly = 245 + ttv;
var volxmax = volx + 26;
var volymin = 250 + ttv;
var volymax = 400 + ttv;
var travel = 22;
//progress
var px = 360 + tth;
var py = 270 + tth;
var pw = 100;
var ph = 130;
var p_drag = 0;
var pxmin = px - pw;
var pymax = py + ph;
var g_timer;

//album art
AlbumArtId = {
front: 0,
back: 1,
disc: 2,
icon: 3
};
var cover = null;

//BUTTON OBJECT=======================================
button = function () {
this._attrb = {};

this.create = function (path_normal, path_hover, path_down) {
  this._attrb.normal = gdi.Image(path_normal);
  this._attrb.hover = gdi.Image(path_hover);
  this._attrb.down= gdi.Image(path_down);
  if (typeof this._attrb.x == "undefined") this._attrb.x= 0;
  if (typeof this._attrb.y == "undefined") this._attrb.y= 0;
  this._attrb.w = this._attrb.normal.Width;
  this._attrb.h= this._attrb.normal.Height;
  if (typeof this._attrb.state == "undefined") this._attrb.state=0;
}

this.draw = function (gr, bx, by, alpha) {
  var image;
  this._attrb.x = bx;
  this._attrb.y = by;
  switch(this._attrb.state)
 {
    case 0:
      image = this._attrb.normal;
      break;
    case 1:
      image = this._attrb.hover;
      break;
    case 2:
      image = this._attrb.down;
      break;
  }
  gr.DrawImage(image, bx, by, this._attrb.w, this._attrb.h, 0, 0, this._attrb.w, this._attrb.h, 0, alpha);
}

this.checkstate = function (action, x, y) {
  switch(action)
  {
    case "down":
      if (x>this._attrb.x && x<this._attrb.x+this._attrb.w && y>this._attrb.y && y<this._attrb.y+this._attrb.h)
      {
        this._attrb.state=2;
window.Repaint();
      } else if (this._attrb.state==2){
        this._attrb.state=0;     
        window.Repaint();
      }
      break;
    case "move":
      if (x>this._attrb.x && x<this._attrb.x+this._attrb.w && y>this._attrb.y && y<this._attrb.y+this._attrb.h)
      {
        this._attrb.state=1;
window.Repaint();
      } else if (this._attrb.state==1){
        this._attrb.state=0;
        window.Repaint();   
      }
      break;
    case "up":
      if (x>this._attrb.x && x<this._attrb.x+this._attrb.w && y>this._attrb.y && y<this._attrb.y+this._attrb.h)
      {
this._attrb.state=1;
      } else {
this._attrb.state=0;
      }
      break;
  }
  return this._attrb.state;
}

}

//BUTTON VARIABLES=====================================
var btn01 = new button;
var btn02 = new button;
var btn03 = new button;
var btn04 = new button;
var btn05 = new button;
var btn06 = new button;
var btn07 = new button;
var btn08 = new button;

var btndir = imgdir +"buttons\\";
var ButtonStates = {normal: 0,hover: 1,down: 2};
var ww;
var wh;
var angulus;

//PAINT===============================================
function on_paint(gr)
{
var coversize = 405
var slider = gdi.image(imgdir + "volslider.png");
var volume = fb.Volume;
var pos = 135 * ((100+volume)/100);
var sliderhz = (pos * -1) + 135;

gr.DrawImage(nocover, 33 + tth, 31 + ttv, coversize, coversize, 0, 0, nocover.Width, nocover.Height);
cover && gr.DrawImage(cover, 33+ tth, 31 + ttv, coversize, coversize, 0, 0, cover.Width, cover.Height, (angulus>=0 && angulus<=359)?angulus:0);
gr.DrawImage(disc, 33 + tth, 31 + ttv, coversize, coversize, 0, 0, disc.Width, disc.Height);

if(fb.IsPlaying || fb.IsPaused){
gr.DrawImage(tt, tth, ttv, tt.Width, tt.Height, 0, 0, tt.Width, tt.Height);
gr.DrawImage(arm,203 + tth, -193 + ttv, arm.Width, arm.Height, 0, 0, arm.Width, arm.Height,angle = ang)};
else{
gr.DrawImage(ttstop,tth,ttv,ttstop.Width,ttstop.Height,0,0,ttstop.Width,ttstop.Height)};

gr.Drawimage(slider,volx,voly + sliderhz,slider.Width,slider.Height,0,0,slider.Width,slider.Height);

//buttons
//menu
btn01.draw(gr,tth + 545,ttv + 435,255);
//album list
btn02.draw(gr,tth + 20,ttv + 20,255);
//search
btn03.draw(gr,tth + 514,ttv + 435,255);
//stop
btn04.draw(gr,tth + 76,ttv + 441,255);
//prev
btn05.draw(gr,tth + 109,ttv + 441,255);
//playpause
btn06.draw(gr,tth + 538,ttv + 108,255);
//next
btn07.draw(gr,tth + 13,ttv + 409,255);
//playback order
btn08.draw(gr,tth + 13,ttv + 357,255);
}

//SIZE==(create buttons)===================================
function on_size() {
ww = window.Width;
wh = window.Height;

btn01.create(btndir+"menu.png", btndir+"menu1.png", btndir+"menu.png");
btn02.create(btndir+"albumlist.png", btndir+"albumlist1.png", btndir+"albumlist.png");
btn03.create(btndir+"search.png", btndir+"search1.png", btndir+"search.png");
btn04.create(btndir+"stop.png", btndir+"stop1.png", btndir+"stop.png");
btn05.create(btndir+"prev.png", btndir+"prev1.png", btndir+"prev.png");
btn06.create(btndir+"playpause.png", btndir+"playpause1.png", btndir+"playpause.png");
btn07.create(btndir+"next.png", btndir+"next1.png", btndir+"next.png");
btn08.create(btndir+"shuffle.png", btndir+"shuffle1.png", btndir+"shuffle.png");

}

//TIME================================================
function on_playback_time(time)
{
    ang = travel * fb.PlaybackTime / fb.PlaybackLength;
     
    if(fb.IsPlaying && !fb.IsPaused) {
btn06.create(btndir+"playpause.png", btndir+"playpause1.png", btndir+"playpause.png");
}
else {
btn06.create(btndir+"playpause.png", btndir+"playpause1.png", btndir+"playpause.png");
}
window.Repaint();
}

//MOUSE LBTN DOWN=====================================
function on_mouse_lbtn_down(x,y){

if(x > volx && x < volxmax && y > volymin && y < volymax){v_drag = 1};

if(x > pxmin && x < px && y > py && y < pymax){p_drag = 1};

//buttons
var state;

if (btn01.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("View/Dockable Panels/Activate/1 - Menu");
}

if (btn02.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("View/Dockable Panels/Activate/2 - Album list");
}

if (btn03.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("Library/Search");
}

if (btn04.checkstate("down",x,y)==ButtonStates.down) {
fb.Stop();
}

if (btn05.checkstate("down",x,y)==ButtonStates.down) {
fb.Prev();
}

if (btn06.checkstate("down",x,y)==ButtonStates.down) {
fb.PlayOrPause();
}

if (btn07.checkstate("down",x,y)==ButtonStates.down) {
fb.Next();
}

if (btn08.checkstate("down",x,y)==ButtonStates.down) {
fb.RunMainMenuCommand("View/Dockable Panels/Activate/3 - Playback order");
}

}

//MOUSE LBTN UP========================================
function on_mouse_lbtn_up(x,y){
on_mouse_move(x,y);
v_drag = 0;

p_drag = 0;

btn01.checkstate("up",x,y);
btn02.checkstate("up",x,y);
btn03.checkstate("up",x,y);
btn04.checkstate("up",x,y);
btn05.checkstate("up",x,y);
btn06.checkstate("up",x,y);
btn07.checkstate("up",x,y);
btn08.checkstate("up",x,y);
window.Repaint();
}

//MOUSE MOVE==========================================
function on_mouse_move(x,y){
if(v_drag){
var v =(y - (voly+115)) /  -100;
v = (v<0) ? 0 : (v<1) ? v : 1;
v = -100 * (1-v);
if(fb.Volume != v)
fb.Volume = v;
}

if(p_drag){
var pxx = (x-px) + pw
var v = pxx/pw;
v = (v<0) ? 0 : (v<1) ? v : 1;
fb.PlaybackTime = fb.PlaybackLength - (fb.PlaybackLength * v);
}

btn01.checkstate("move",x,y);
btn02.checkstate("move",x,y);
btn03.checkstate("move",x,y);
btn04.checkstate("move",x,y);
btn05.checkstate("move",x,y);
btn06.checkstate("move",x,y);
btn07.checkstate("move",x,y);
btn08.checkstate("move",x,y);
}

//MOUSE LEAVE==========================================
function on_mouse_leave() {
btn01.checkstate("up",0,0);
btn02.checkstate("up",0,0);
btn03.checkstate("up",0,0);
btn04.checkstate("up",0,0);
btn05.checkstate("up",0,0);
btn06.checkstate("up",0,0);
btn07.checkstate("up",0,0);
btn08.checkstate("up",0,0);

window.Repaint();
}

//MOUSE WHEEL=========================================
function on_mouse_wheel(delta){
if(delta>0)
fb.VolumeUp();
else
fb.VolumeDown();
}

//VOLUME CHANGE=======================================
function on_volume_change(val){
window.Repaint();
}

//SEEK================================================
function on_playback_seek(time){
window.Repaint();
}

//ALBUM ART============================================
function get_album_art(metadb) {
if (metadb)
// Get front cover
return utils.GetAlbumArt(metadb.RawPath, AlbumArtId.front);
}
cover = get_album_art(fb.GetNowPlaying());

//NEW TRACK===========================================
function on_playback_new_track(metadb) {
angulus=0;
cover = get_album_art(metadb);
window.Repaint();
}

function on_playback_stop()
{
if(g_timer){
window.KillTimer(g_timer);
}
window.Repaint();
}

// ==============================================================/ Playback starting
function on_playback_starting(cmd, is_paused)
{
g_timer = window.CreateTimerInterval(33);
window.Repaint();
}

// ==============================================================/ Redraw more than once per sec
function on_timer(id)
{
    angulus = (angulus>360)?0:angulus+10;
window.Repaint();
}

//EOF

try it.

WSH Panel Mod

Reply #314
works fine here. I've added a cover rotation 

not perfect but it gives you the way to do it 


try it.


hey, i like that...
  i was playing around with the cover rotation too, but couldn't get it to rotate at a decent speed, which you've solved nicely - have to fiddle with it a bit more, but it's sure a good start!
i'er heights

WSH Panel Mod

Reply #315
be carefull, CPU % is still very high with my settings, i hope an optimization is possible ... it is !! just find (maybe) the solution! too much enthusiastic  ... keep searching a solution.


WSH Panel Mod

Reply #316
Im using the preview mode component.
Is it somehow with WSH panel mod possible to create a button which will keep highlighted when its on?
Playback/Preview mode
Since currently i just got a button with Panel Stack Splitter but u cant see if its on or off now 

WSH Panel Mod

Reply #317
Its me again crying for help... 

I've set up some properties and want to update them with context menu.
I've set it up like this (code snippet of a class only):
Code: [Select]
    this.RatingMode = function () {
        this.rm_cur = window.GetProperty("Rating Mode (0, 1 or 2)", 0);
        if (typeof(this.rm_cur) != "number" || this.rm_cur < 0)
            this.rm_cur = 0;
        else if (this.rm_cur > 2)
            this.rm_cur = 2;

        return this.rm_cur;
    }
and wanted to update this way:
Code: [Select]
function on_mouse_rbtn_up(x, y) {
var MF_STRING = 0x00000000;
var menu = window.CreatePopupMenu();
var idx;
 
menu.AppendMenuItem(MF_STRING, 1, "Properties");
menu.AppendMenuItem(MF_STRING, 2, "Configure...");
menu.AppendMenuItem(MF_STRING, 3, "Rating Mode 1");
idx = menu.TrackPopupMenu(x, y);
 
if (idx == 1)
window.ShowProperties();
else if (idx == 2)
window.ShowConfigure();
else if (idx == 3)
window.SetProperty("Rating Mode (0, 1 or 2)", 1);
 
return true;
}
But it doesn't updates the properties immediately.
It still updates on the next track.
Where's my "bug"?

Thanks in advance

WSH Panel Mod

Reply #318
There's a new problem somewhere in my script, i guess...
Maybe someone could take a look at it.

In addition that the properties updates only on new track i sometimes get an error, when i open the context menu, wait some time and click then outside the menu or the panel (because i don't want to change the option):
Code: [Select]
Script terminated due to the panel (HWND: 0x590350) seems to be unresponsive, please check your script (usually infinite loop).
It must be caused by the context menu, since i never got this error before.

This is my whole script (please don't laugh. I know i better should breed sheeps instead of scripting...  )
Code: [Select]
var imgPath = fb.FoobarPath + "DarkOne\\Rating\\";
var settingsPath = fb.FoobarPath + "DarkOne\\Settings\\";

var fso = new ActiveXObject("Scripting.FileSystemObject");
var today = new Date();
var opt_read, bool;

var plycntr = fb.TitleFormat("%play_count%");

var g_tooltip = window.CreateTooltip();
var g_down = false;

// Code for "current date" file creation ===========================
set_current_date();

function update_option(optvalue) {
var f1, ts, ts2, s;

ts = fso.OpenTextFile(settingsPath + "cur_date.txt", 1);
s = ts.ReadLine();
ts.Close();

f1 = fso.MoveFile(settingsPath + "cur_date_" + s, settingsPath + "cur_date_" + optvalue);
ts2 = fso.OpenTextFile(settingsPath + "cur_date.txt", 2);
ts2.WriteLine(optvalue);
ts2.Close();
}

function read_option(initvalue) {
var ts, ts2, s;

if (file_exists(settingsPath + "cur_date.txt")==true) {
ts = fso.OpenTextFile(settingsPath + "cur_date.txt", 1);
s = ts.ReadLine();
ts.Close();
return s;
} else {
ts = fso.CreateTextFile(settingsPath + "cur_date.txt", 2);
ts.WriteLine(initvalue);
ts.Close();
ts2 = fso.CreateTextFile(settingsPath + "cur_date_" + initvalue, 2);
ts2.Close();
return initvalue;
}
}

function file_exists(chemin) {
bool = fso.Fileexists(chemin);
return bool;
}

function set_current_date(){
var s, s1, s2, s3;
s1 = today.getFullYear();
s2 = (today.getMonth() + 1);
s3 = today.getDate();
s = s1*10000 + s2*100 + s3;
opt_read = read_option(s);
update_option(s);
}

function RGBA(r, g, b, a) {
return ((a << 24) | (r << 16) | (g << 8) | (b));
}

// Rating button object ============================================
function RatingButton(x, y, rW ) {
this.left = x;
this.top = y;
this.ratingWidth = rW;

this.normalImage = null;
this.ratingImageArray = null;

this.active = true;

this.img = null;
this.curRating = -1;
this.controler = null;

this.toolTips = new Array("Bad", "Average", "Good", "Very Good", "Excellent");

this.changeRating = function() {
if (this.curRating < 0 || !this.active ) {
if (this.normalImage)
this.img = gdi.Image(this.normalImage);
} else {
if (this.ratingImageArray) {
if (this.ratingImageArray[this.curRating])
this.img = gdi.Image(this.ratingImageArray[this.curRating]);
}
}
window.Repaint();
}

this.showToolTip = function() {
g_tooltip.Deactivate();
if (!this.active) return;
if (this.curRating > -1 && fb.IsPlaying) {
var ratingIndex = (this.curRating > 4) ? 4 : this.curRating;
if (this.controler.getModus() == 2 && this.controler.IsInLibrary())
g_tooltip.Text = "Playcounts: " + plycntr.Eval();
else
g_tooltip.Text = this.toolTips[ratingIndex];

g_tooltip.Activate();
}
}

this.draw = function (gr) {
if (this.img)
this.img && gr.DrawImage(this.img, this.left, this.top, this.img.Width, this.img.Height, 0, 0, this.img.Width, this.img.Height);
}

this.onClick = function () {
if (!this.active) return;
if (this.curRating > -1)
this.controler.setRating(this.curRating + 1);
}

this.on_mouse_move = function (x, y) {
if (!this.active) return;
var ratingIndex = 0;
var _x = x - this.left;
if (_x > 0 && _x < this.ratingWidth * 5) {
ratingIndex = Math.floor( _x / this.ratingWidth);
ratingIndex = ratingIndex > 5 ? 5 : ratingIndex;
if (this.curRating != ratingIndex) {
this.curRating = ratingIndex;
this.changeRating( );
this.showToolTip( );
}
}
}

this.on_mouse_leave = function() {
this.curRating = -1;
this.changeRating();
g_tooltip.Deactivate();
}

this.setRatingImages = function(normalImg, hoverImg) {
this.normalImage = normalImg;
this.ratingImageArray = hoverImg;
this.changeRating();
}

this.setControler = function(controler) {
this.controler = controler;
}

this.setActive = function(active) {
this.active = active;
}
}

// Controler to serve the button object ============================
function StateControler(ratingButton) {
this.ratingButton = ratingButton;
this.ratingButton.setControler(this);
this.curMetadb = null;
this.RATING = "RATING";
this.curModus = null;
this.active = true;

// Colours for the different rating modes
var Colours = {
manRating:"White",
dataBase:"Yellow",
playCount:"Green",
autoRating:"Blue"
}

// Get rating mode from properties window
this.RatingMode = function () {
this.rm_cur = window.GetProperty("Rating Mode", 0);
if (typeof(this.rm_cur) != "number" || this.rm_cur < 0)
this.rm_cur = 0;
else if (this.rm_cur > 2)
this.rm_cur = 2;

return this.rm_cur;
}

// Get option for autorating on or off in mode 0 and 1 from properties window
this.AutorateOn = function () {
this.ar_on = window.GetProperty("Show Autorating", true);
return this.ar_on;
}

// Get the limit playcounts should be displayed in mode 2 from properties window
this.CountLimit = function () {
this.cntlmt = window.GetProperty("Playcounter Limit", 50);
if (typeof(this.cntlmt) != "number")
this.cntlmt = 50;
else if (this.cntlmt < 0)
this.cntlmt = 0;

return this.cntlmt;
}

this.setRating = function(ratingIndex) {
if (!this.active) return;
var modus = this.RatingMode();
this.curModus = modus;
if (modus == 2) {
if (!this.IsInLibrary())
this.SetMetaRating(ratingIndex);
} else if (modus == 1)
this.SetMetaRating(ratingIndex);
else {
if (this.IsInLibrary())
fb.RunContextCommand("Rating" + "/" + ratingIndex);
else
this.SetMetaRating(ratingIndex);
}
this.on_metadb_changed();
}

this.SetMetaRating = function(rating) {
if (this.curMetadb)
this.curMetadb.UpdateFileInfoSimple(this.RATING, rating);
}

this.init = function () {
this.on_playback_new_track(fb.GetNowPlaying());
}

this.on_playback_new_track = function(metadb) {
if (this.curMetadb) {window.UnwatchMetadb();}
this.curMetadb = metadb;
if (this.curMetadb) {
on_metadb_changed();
window.WatchMetadb(this.curMetadb);
}
}

this.on_metadb_changed = function() {
if (this.active) {
var modus = this.RatingMode();
this.curModus = modus;
if (modus == 2) {
if (this.IsInLibrary())
this.SetRatingDisplay(Colours.playCount, this.GetPlayCounts(), modus);
else
this.SetRatingDisplay(Colours.manRating, this.GetMetaRating(), modus);
} else {
if (this.IsMetaRating())
this.SetRatingDisplay(Colours.manRating, this.GetMetaRating(), modus);
else {
var dbRating = this.GetDBRating();
if (dbRating > 0)
this.SetRatingDisplay(Colours.manRating, dbRating, modus);
else
this.SetRatingDisplay(Colours.autoRating, this.GetAutoRating(), modus);
}
}
} else
this.ratingButton.setRatingImages(imgPath + "Grey.png", null);

window.Repaint();
}

this.IsInLibrary = function() {
if (this.curMetadb)
return fb.IsMetadbInMediaLibrary(this.curMetadb);
else
return false;
}

this.GetDBRating = function() {
return fb.TitleFormat("[%rating%]").Eval();
}

this.IsMetaRating = function() {
return (this.GetMetaRating() > 0);
}

this.GetMetaRating = function() {
if (this.curMetadb) {
var fileInfo = this.curMetadb.GetFileInfo();
if (fileInfo) {
var idx = fileInfo.MetaFind(this.RATING);
if (idx > 0) {
var rating = fileInfo.MetaValue(idx, 0);
return (rating > 5) ? 5 : rating;
} else
return 0;
}
} else
return 0;
}

this.GetAutoRating = function(){
return this.GetCounter(true);
}

this.GetPlayCounts = function() {
return this.GetCounter(false);
}

// Calculation for autorating
this.GetCounter = function(autoRating) {
var ar_count;
if (this.AutorateOn()) {
var fpy = fb.TitleFormat("$year(%first_played%)").Eval();
var fpm = fb.TitleFormat("$sub($month(%first_played%),1)").Eval();
var fpd = fb.TitleFormat("$day_of_month(%first_played%)").Eval();
var fday = new Date(fpy, fpm, fpd);
var one_day = 1000*60*60*24;
var ar_days = Math.floor((today.getTime() - fday.getTime())/one_day);
ar_count = (plycntr.Eval()*5) - Math.floor(ar_days/7.3);
} else
ar_count = 0;

var counter = (autoRating) ? ar_count : plycntr.Eval();
var count_div = (autoRating) ? 10 : this.CountLimit()/5;
var rating = Math.floor(counter/count_div);
return (rating > 5) ? 5 : ((rating < 0) ? 0 : rating);
}

this.SetRatingDisplay = function( normalColour, ratingIndex, modus ) {
var hoverImg = null;
if (modus == 1)
hoverImg = this.getHoverImages(Colours.manRating);
else if (modus == 2) {
if (!this.IsInLibrary())
hoverImg = this.getHoverImages(Colours.manRating);
} else {
if (this.IsInLibrary())
hoverImg = this.getHoverImages(Colours.dataBase);
else
hoverImg = this.getHoverImages(Colours.manRating);
}

var normalImg = null;
normalImg = imgPath + normalColour + ratingIndex + ".png";

this.ratingButton.setRatingImages(normalImg, hoverImg);

CollectGarbage();
}

this.getHoverImages = function(colour) {
var hoverImageArray = new Array();
for (var i = 1; i < 6; i++)
hoverImageArray.push(imgPath + colour + "MH"+ i +".png");

return hoverImageArray;
}

this.getModus = function() {
return this.curModus;
}

this.setActive = function(active) {
this.active = active;
}
}

// Create objects ==================================================
button = new RatingButton(0, 0, 16);
stateControler = new StateControler(button);
stateControler.init();

// Mouse events ====================================================
function on_mouse_move(x, y) {
button.on_mouse_move(x, y);
}

function on_mouse_lbtn_down(x, y) {
g_down = true;
}

function on_mouse_lbtn_up(x, y) {
if (g_down)
button.onClick(x, y);
g_down = false;
}

// Context menu
function on_mouse_rbtn_up(x, y) {
var MF_STRING = 0x00000000;
var MF_GRAYED = 0x00000001;
var MF_SEPARATOR = 0x00000800;
var menu = window.CreatePopupMenu();
var idx;

var ar_MF = (stateControler.RatingMode() == 2) ? MF_GRAYED : MF_STRING;
var ar_text = stateControler.AutorateOn() ? "Disable" : "Show";
var ar_option = (stateControler.AutorateOn()) ? false : true;
 
menu.AppendMenuItem(MF_STRING, 1, "Store ratings in the database");
menu.AppendMenuItem(MF_STRING, 2, "Store ratings in the file tags");
menu.AppendMenuItem(MF_STRING, 3, "Show stars calculated by playcounter");
menu.AppendMenuItem(MF_SEPARATOR, 0, 0);
menu.AppendMenuItem(ar_MF, 4, ar_text + " autorating calculation");
menu.AppendMenuItem(MF_SEPARATOR, 0, 0);
menu.AppendMenuItem(MF_STRING, 5, "Properties");
menu.AppendMenuItem(MF_STRING, 6, "Configure...");
idx = menu.TrackPopupMenu(x, y);
 
if (idx == 1)
window.SetProperty("Rating Mode", 0);
else if (idx == 2)
window.SetProperty("Rating Mode", 1);
else if (idx == 3)
window.SetProperty("Rating Mode", 2);
else if (idx == 4)
window.SetProperty("Show Autorating", ar_option);
else if (idx == 5)
window.ShowProperties();
else if (idx == 6)
window.ShowConfigure();
 
return true;
}

function on_mouse_leave() {
if(button)
button.on_mouse_leave();
}

// Drawing the panel ===============================================
function on_paint(gr) {
gr.FillSolidRect(0, 0, window.Width, window.Height, RGBA(19, 30, 38, 255));

if (fb.IsPlaying) {
if (button)
button.draw(gr);
} else {
var stop_img = gdi.Image(imgPath + "Grey.png");
gr.DrawImage(stop_img, 0, 0, 80, 16, 0, 0, stop_img.Width, stop_img.Height);
}
}

// Refresh =========================================================
function on_playback_stop() {
window.Repaint();
}

function on_playback_new_track(metadb) {
if (fb.PlaybackLength < 0 || metadb.RawPath.indexOf("cdda://" ) == 0 || metadb.RawPath.indexOf("FOO_LASTFM" ) == 0) {
stateControler.setActive(false);
button.setActive(false);
} else {
stateControler.setActive(true);
button.setActive(true);
}
stateControler.on_playback_new_track(metadb);
}

function on_metadb_changed() {
stateControler.on_metadb_changed( );
}
I hope there's someone outside who has any ideas about this and my above problem
Thanks

WSH Panel Mod

Reply #319
Ok, solved problem one in the meantime
But not the second...
I still get the error message "Script terminated due to the panel (HWND: 0x590350) seems to be unresponsive, please check your script (usually infinite loop)" sometimes, when opened the context menu and doesn't choose an option but click elsewhere in foobar2000.

WSH Panel Mod

Reply #320
Hi.
I have some issues with WHS.
First of all ,during the day i got message (after restart PC) :

Buttons as You see are disappear.I was reloading script  a few times but without results.Actually that was even worst.Whole windows are become to be a green with dB inside (unfortunately i haven't picture of that).
Then i imported once again fcl. and another message:


This is not true, because i did install that WSC.
I'm using Windows Se7en and before that everything worked properly.

WSH Panel Mod

Reply #321
@tedgo:
I'll check it later

@El Loco Chocko:
1. First make sure you are using the latest Beta version of WSH Panel Mod, that popup message means some scripts hangs previously executed, if you don't like that behavior, disable it in fb2k Preferences->WSH Panel Mod, set timeout to 0.
2. WSH Panel doesn't require Window Script Control, chronflow does.


WSH Panel Mod

Reply #323
@T.P Wang
Thanks
But the first problem (properties window wouldn't update) is solved.
Was a missing line in the script. Not wsh panel mods fault 

The second problem still exists.
It seems that waiting too long for choosing an option in the context menu causes the "unresponsive" error.
I haven't found an "infinite loop" in my script (but maybe i looked over it only...).

WSH Panel Mod

Reply #324
Does anyone know how to show/hide a panel with this component? 
I'm talking about a panel inside a PSS.
<insert signature here>