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: JScript Panel script discussion/help (Read 300878 times) previous topic - next topic
0 Members and 2 Guests are viewing this topic.

Re: JScript Panel script discussion/help

Reply #475
I've fixed up all 3 of Falstaff/Br3tt's JS Smooth scripts so they work in the latest version of JScript Panel. It was some badly formatted if/else statements that prevented it working with the Chakra engine.

https://github.com/19379/JS-Smooth-Scripts-By-Br3tt

@Falstaff, if you read this sometime, the new component didn't like you coding like this...

Code: [Select]
if (something) {

};
else {

}

It had to be replaced with

Code: [Select]
} else {

edit: Just realised I missed the catch statements so an updated version has been uploaded.


ok, seen, i'll be aware of that.

Re: JScript Panel script discussion/help

Reply #476
There is a js-script panel which changes in the size according to the toggle notify. (for example, h1 = 500, h2=1)
In other word,
for toggle --> panel height = h1
for !toggle --> panel height = h2

What I want to do is (%path% is "youtube.com/watch~~~~")
for toggle and %path% include 'youtube' --> panel height = h1
for toggle, and %path% Not include 'youtube' --> panel height = 10
for !toggle  --> panel height = h2

So, I tried like this,
Code: [Select]
var chk_yt = "$left(%path%,7)";

function on_notify_data(name, info) {
    switch(name) {
  case "center_panel":
                      toggle = !toggle;
                      window.SetProperty("toggle", toggle);
                           if(toggle) {
if(chk_yt == "youtube") {
window.MinHeight = h1;
window.MaxHeight = h1;
} else {
window.MinHeight = 10;
window.MaxHeight = 10;
};
                           } else {
                                 window.MinHeight = h2;
                                 window.MaxHeight = h2;
                           };
                           break;
}
}
But, it doesn't work as I wanted. Could anyone give me some hint to make this work?


Re: JScript Panel script discussion/help

Reply #478
That bit of code needs to go inside the function, If it runs outside the function at script startup, the value will never update.

If unsure, you can always output stuff to the console to check the value is what you expect it to be.

Code: [Select]
fb.trace(chk_yt);

Re: JScript Panel script discussion/help

Reply #479
zeremy & marc2003,
Thank you for your kind help. It was very helpful.

Even though my current foobar is very close to the final target, there is a small problem.
When I change tracks between 'youtube' songs and 'non-youtube' songs, I want the size(panel height) of jsscript panel to automatically be changed according to the source of track.

youtube track --> panel height = h1
non-youtube track  --> panel height = 1


Could you let me know how to change  the following scripts for that purpose?
Code: [Select]
function on_size() {
    ww = window.Width;
    wh = window.Height;
    var chk_yt = fb.TitleFormat("%path%").Eval().substring(0,7);
    if(chk_yt == "youtube") {
        if(toggle) {
            window.MinHeight = h1;
            window.MaxHeight = h1;
        } else {
            window.MinHeight = 1;
            window.MaxHeight = 1;
        };
    } else {
        window.MinHeight = 1;
        window.MaxHeight = 1;
    };
    window.MinWidth = 1;
    window.MaxWidth = 1;
}


function on_notify_data(name, info) {
    switch(name) {
        case "height_notify":
            max_h = (info - 3);
        case "width_notify":
            height = Math.round(info * 0.5625);
            if(height >= max_h) {
                h1 = max_h;
            } else {
                h1 = Math.round(info * 0.5625)-1;
            };
            window.MinHeight = 1;
            window.MaxHeight = 1;
            break;
        case "center_pane":
            toggle = !toggle;
            window.SetProperty("toggle", toggle);
            var chk_yt = fb.TitleFormat("%path%").Eval().substring(0,7);
            if(chk_yt == "youtube") {           
                if(toggle) {
                    window.MinHeight = h1;
                    window.MaxHeight = h1;
                } else {
                    window.MinHeight = 1;
                    window.MaxHeight = 1;
                }
            } else {
                window.MinHeight = 1;
                window.MaxHeight = 1;
            };
            break;
    }
}

Re: JScript Panel script discussion/help

Reply #480
I see you are using function on_notify_data(name, info).
Could you clarify if you need to notify from a jscript panel another second jscript panel with window.NotifyOthers .
Are they two separate panels or do you just want one jscript panel height to change when youtube is playing?
What is the purpose of the variable toggle?

Re: JScript Panel script discussion/help

Reply #481
I see you are using function on_notify_data(name, info).
Could you clarify if you need to notify from a jscript panel another second jscript panel with window.NotifyOthers .
Are they two separate panels or do you just want one jscript panel height to change when youtube is playing?
What is the purpose of the variable toggle?
My configuration is like this.
I have several panels such as "playlists, album art, biography, play control, foo_youtube, etc"
I want 'foo_youtube' panel to be size-adjusted according to the foobar window & other panel sizes, and to be toggled by 'toggle buttons' in a different jscript panel.
For this purpose, I made created two panels with 'left/right'splitter. And 'foo_youtube is implemented in the left panel, and the above code is implemented in the right panel.
So, by changing the height of the right panel, I can hide/show the foo_youtube panel which has 16:9 ratio.
"height_notify" and "width_notify" are notified from the other jscript panels and are used to adjust the right panel height.

At this moment, I can toggle the foo_youtube panel by clicking the 'toggle button'.
The purpose of toggle : "Sometimes I want to see the youtube video, sometimes only want to listen the youtube audio by hiding 'foo_youtube' panel."
But, some playlists have mixes of "youtube songs" and 'non-youtube songs."
For those playlists, it would be nice if the 'foo_youtube' panel can be hide/show automatically by checking if the now-playing song is coming from 'youtube' site.

I hope that the above explanation make clear my intention.
Thank you agian for your interest and help.

 

Re: JScript Panel script discussion/help

Reply #482
You can send the value if "youtube" from your "control panel" on each new track played with:
Code: [Select]
function on_playback_new_track(){
var chk_yt = fb.TitleFormat("%path%").Eval().substring(0,7);
window.NotifyOthers("center_pane",chk_yt);
}

In the panel to be notified add:

Code: [Select]
function on_notify_data(name, info) {
    switch(name) {
        case "center_pane":
            if(info == "youtube") {           
                if(toggle) {
                    window.MinHeight = h1;
                    window.MaxHeight = h1;
                } else {
                    window.MinHeight = 1;
                    window.MaxHeight = 1;
                }
            } else {
                window.MinHeight = 1;
                window.MaxHeight = 1;
            };
            break;
    }
}

toogle and h1 will have to be defined beforehand for it to work though.

The panel cannot be in a PSS  https://github.com/19379/foo-jscript-panel/blob/master/component/docs/Interfaces.txt#L759

I lost you when you referred to showing/hiding the video panel ( even after a cup of coffee  :D ) , you can only change the jscript panel size,

Re: JScript Panel script discussion/help

Reply #483
toogle and h1 will have to be defined beforehand for it to work though.
I lost you when you referred to showing/hiding the video panel ( even after a cup of coffee  :D ) , you can only change the jscript panel size,
Thank you very very much for your help.
With minor optimization for your above  code, my foobar is fianlly working as I wanted

For the reference, I leave my final code for my purpose.

In the foobar control jscript  panel,
Code: [Select]
function on_playback_new_track(){
var chk_yt = fb.TitleFormat("%path%").Eval().substring(0,7);
window.NotifyOthers("chk_yt",chk_yt);
}

In the target jscript paenl,
Code: [Select]
function on_notify_data(name, info) {
    switch(name) {
case "center_pane":
            toggle1 = !toggle1;
            window.SetProperty("toggle1", toggle1);
            toggle = toggle1;
            if(chk_yt == "youtube") {
                if(toggle1) {
                    window.MinHeight = h1;
                    window.MaxHeight = h1;
                } else {
                    window.MinHeight = 1;
                    window.MaxHeight = 1;
                };
            } else {
                toggle = false;
                window.MinHeight = 1;
                window.MaxHeight = 1;
            };
            break;
        case "chk_yt":
            chk_yt = info;
            if(info == "youtube") {
                toggle = toggle1;               
                if(toggle1) {
                    window.MinHeight = h1;
                    window.MaxHeight = h1;
                } else {
                    window.MinHeight = 1;
                    window.MaxHeight = 1;
                };
            } else {
                toggle = false;
                window.MinHeight = 1;
                window.MaxHeight = 1;
            };
            break;
    }
}

Re: JScript Panel script discussion/help

Reply #484
I have a question about  on_playback_stop()  & on_playback_new_track()

Now, I'm using the below code to notify 'stop' to the other panel.
Code: [Select]
function on_playback_stop() {
    window.NotifyOthers("stop_notify","");
buttons.update();
    window.Repaint();
}
Function "on_playback_new_track()"  don't have any NotifyOthers. But, whenever a new track is played according to the plalist queue,  it looks like 'stop_notify' is activated.( playback_new_track --> playback_stop + playback_starting ?)

How can I notify 'stop_notify' only  when I "Really" stop playing foobar?


Re: JScript Panel script discussion/help

Reply #486
docs\callbacks.txt

https://github.com/19379/foo-jscript-panel/blob/master/component/docs/Callbacks.txt#L133L134

Something like

Code: [Select]
function on_playback_stop(reason) {
    if (reason < 2) {
        window.NotifyOthers("stop_notify","");
    }
    buttons.update();
    window.Repaint();
}
Wow. It's so simple.  I didn't know that there are those documents under jscript-panel plugin.
Thank you for your help.

Re: JScript Panel script discussion/help

Reply #487
Hi marc2003,

Firstly, thank you for your work on JScript Panel, and thank you for sharing it with the fb2k community.

I'm using your album art script example, and I noticed that the included shadow overlay PNG didn't blend so well at the edges - so I made another version in Photoshop that fixes this and wanted to share it with you snd the community.

Here's the download to the revised shadow.png: http://i.imgur.com/js04cN8.png
And here's the comparison against your original version: http://i.imgur.com/plXl0Nw.png

On a side note, I disabled the forced crop/fill option that you specify when using the CD case background, because some of the releases in my collection are in mini-CD single format, which looks bad when forced to fill the extents of the jewel case. Perhaps you might want to consider making this a toggle that can be selected when using the CD case?

Re: JScript Panel script discussion/help

Reply #488
I'll use your updated image in the next release. Thanks.

As for the aspect, I always thought cropping the image was best without giving a choice. I think gaps around non square images look bad on the case background?? Still, I suppose I can restore the option to let people choose.

edit: changes have been made in this commit.

Re: JScript Panel script discussion/help

Reply #489
I think gaps around non square images look bad on the case background?? Still, I suppose I can restore the option to let people choose.

Well, it definitely is not realistic for a tall, rectangular cover to sit inside a CD jewel case tray, but for the few releases I have with album art in that format, it doesn't bother me - seeing the entire album art is a higher priority.

Thanks for the commit! :)

Re: JScript Panel script discussion/help

Reply #490
I have a perhaps silly question about debugging scripts running inside JSPanel. Here's an example error:

JScript Panel (Rating by marc2003): Microsoft JScript runtime error:
'_' is undefined
File: <main>
Line: 13, Col: 1
<source text only available at compile time>

What does "source text only available at compile time" mean? Can I actually see more debug info during... compile time? What does "compile time" mean? Can I somehow debug the C++ component using Visual Studio if I launch foobar? Or can I debug the JS script from a tool such as Webstorm? (although this second variant I guess would be a bit more technically challenging to perform since it requires somehow connecting the IDE to the browser VM running under Foobar).

Re: JScript Panel script discussion/help

Reply #491
Just ignore the stuff you don't understand. Line 13 and '_' is undefined is actually all the information you need. No fancy IDE/debugger is going to be any more helpful.

Anyway, the reason for that error is that important files are missing because you didn't install the component properly. I did link to the foolproof instructions but I guess you decided you were bit of a gangster and extracted the dll only?

http://wiki.hydrogenaud.io/index.php?title=Foobar2000:How_to_install_a_component

Re: JScript Panel script discussion/help

Reply #492
Hey :). I managed to fix the error because the next error was quite clear. Yes, I initially only extracted the DLL. But it wasn't because I wanted more street cred' :). It was because "docs" and "samples" didn't seem to me to need to belong in the components folder. But I'm fine with whatever! :). The component ROCKS and I'm very enthusiastic to work with it now that I finally managed to set some time for this.

I'm trying to build a multi-tag tool. Something that allows to set multiple tags to song and filter on them. Things like a song's style, mood, vocal style, lyrical theme, tempo. What I'm aiming is to allow a user to create auto playlists by requesting, for example, "all songs that feature female vocals, have a slow tempo and have a mystic atmosphere". I plan to perhaps build relations between tags so that similar suggestions are found based on the selected tags.

I do have a few questions to start with:

There is no dropdown list component from what I see? I can probably achieve a similar functionality by creating context menus with options, something I've already seen used in some of your samples. But what if there are more items that fit on the screen? What is your recommendation in that case? Should I use GDI to create my own component?

I'd like to implement an autocomplete textbox. The purpose being that when you start typing any tag, you get a suggestion that you can "tab" to autocomplete. This should be pretty easy right? Just create a hotkey hook. I hope TAB... won't tab me out of the panel :).

I'm kind of aiming to go into the Columns UI code anyway and see if I can find a way to install shortcuts for focusing on various panels, as I am very keyboard driven and would love to operate Foobar as much as possible using keyboard only.

Re: JScript Panel script discussion/help

Reply #493
If the menu doesn't fit on screen, there will be arrows to scroll up/down. Example....

Code: [Select]
// ==PREPROCESSOR==
// @import "%fb2k_component_path%samples\complete\js\lodash.min.js"
// @import "%fb2k_component_path%samples\complete\js\helpers.js"
// ==/PREPROCESSOR==

var items = _.range(0, 1000);

function on_mouse_lbtn_up(x, y) {
var m = window.CreatePopupMenu();
_.forEach(items, function (i) {
m.AppendMenuItem(MF_STRING, i + 1, "Menu Item " + i);
});
var idx = m.TrackPopupMenu(x, y);
if (idx > 0)
fb.ShowPopupMessage("You selected item " + (idx - 1));
m.Dispose();
}

Falstaff/Wilb both have scripts available with fully functioning text boxes that you can type in. Look at jsplaylist-mod (included with component) or Wilb's Library tree script.

Re: JScript Panel script discussion/help

Reply #494
Perfect. Thank you for all the pointers :). Helpful as usual. Thank you for your patience as you explain these things. I've always been impressed by the quality of work that went into extending Foobar's functionality by all the community.

It's awesome that you implemented autocompletion in the panel editor itself! I suppose this is the preferred method of editing the scripts?

I like to browse various code samples in parallel with coding my own script, especially since I'm quite new at this. For now I'm using IntelliJ for that, since it helps a bit with the coloring. I don't suppose there are ways to make an IDE do code completion based on your .api files. The only reason I'm asking is because code navigation is easier with an IDE thanks to things like "go to definition" and various hover hints, etc etc.

Re: JScript Panel script discussion/help

Reply #495
Whoops. Only now after a bit more investigation I realized that all UI work done in a JSPanel has to be done using GDI calls. Basically components have to be created from scratch.

I am probably missing something here :).

I don't really understand why not to develop the component in Visual Studio then, where there is the possibility of using Win32 API to create comboboxes and such. Plus, there's a tighter integration with the rest of the Foobar ecosystem such as Columns UI.

If I'm failing to see something important, please tell me. I haven't yet started any actual coding :). Still investigating SDKs. I got some Visual Studio builds going too. I know my way around C++, although I never went in-depth with it.

Re: JScript Panel script discussion/help

Reply #496
I don't really understand why not to develop the component in Visual Studio then, where there is the possibility of using Win32 API to create comboboxes and such. Plus, there's a tighter integration with the rest of the Foobar ecosystem such as Columns UI.
That's the entire point of JScript: (kinda) user-friendly way to create 'components'. Especially useful, when you need a simple panel (e.g. a panel that displays some text, or may be a button) - creating a separate full component for every such panel is just pointless.
 
Just compare writing a JS program (with run-time compilation) in JScript windows w\o any need of external software or IDE vs writing a full component based on foobar SDK with all the dependencies, build parameters, dll's and etc, which can't be done without having a proper build environment (compiler/IDE).

But, yeah, if you want to develop a high performance component with the full usage of WinApi, then JScript is not really suitable for your needs.

Re: JScript Panel script discussion/help

Reply #497
Last.fm have updated their website to use https therefore the scripts need to be updated. Edit your text.js/thumbs.js files and replace http with https.

thumbs.js
Code: [Select]
this.xmlhttp.open("GET", "https://www.last.fm/music/" + encodeURIComponent(this.artist) + "/+images", true);

I applied the same edit to the last.fm albumart downloader script, which I just found out is not working anymore, but it doesn't solve the problem. Is there anyway to get the script back to work? Did it actually stop working in the first place or did I mess up something?
I'm late

Re: JScript Panel script discussion/help

Reply #498
Last.fm have updated their website to use https therefore the scripts need to be updated. Edit your text.js/thumbs.js files and replace http with https.

thumbs.js
Code: [Select]
this.xmlhttp.open("GET", "https://www.last.fm/music/" + encodeURIComponent(this.artist) + "/+images", true);

I applied the same edit to the last.fm albumart downloader script, which I just found out is not working anymore, but it doesn't solve the problem. Is there anyway to get the script back to work? Did it actually stop working in the first place or did I mess up something?


Sorry, answering myself: yes, I did mess up something. The script had been updating the album-art.ini file even if the download didn't work and after editing the script I tested it on the same tracks. After erasing the last added lines in the ini file the script was able to download the album covers.
I'm late

Re: JScript Panel script discussion/help

Reply #499
I'm trying to create a simple menu button but I can't figure out how to display a "pressed" image that appears while the contextmenu popup is open. The default button only has normal and hover states, and no matter what I try I can't seem to swap the normal image for the pressed one on-the-fly. Any help would be much appreciated. My code is below:

Code: [Select]
// ==PREPROCESSOR==
// @name "MainMenuManager All-In-One"
// @author "YBStone / T.P Wang / marc2003"
// @import "%fb2k_component_path%docs\flags.txt"
// @import "%fb2k_component_path%docs\helpers.txt"
// ==/PREPROCESSOR==

var tooltip = window.CreateTooltip();
// buttons is defined in docs\helpers.txt
var b = new buttons();

var mhx = false;
var pressed = false;
var img1 = "C:\\fooTest\\test01.png";
var img2 = "C:\\fooTest\\test02.png";
var img3 = "C:\\fooTest\\test03.png";
var img4 = "C:\\fooTest\\test04.png";
var img5 = "C:\\fooTest\\test05.png";
var imgN;
var imgH;
var imgP;

if(pressed == true)
    imgP = img1;
else
    imgP = img2;
 
//button is defined in docs\helpers.txt
//arguments are x, y, w, h, {normal image, hover image is optional}, function, tooltip
b.buttons.menu = new button(0, 0, 60, 60, {normal : imgP, hover: img5},function () { menu(); }, "");

function on_paint(gr) {
b.paint(gr);
}

function on_mouse_move(x, y) {
b.move(x, y);
}

function on_mouse_lbtn_up(x, y) {
    if( mhx == false ){
        b.lbtn_up(x, y);
        mhx = true;}
    else if ( mhx == true ){
        mhx = false;}
  
    if( pressed == false ){
        pressed = true;}
    else if( pressed = true ){
        pressed = false;}
}

function on_mouse_leave(x, y) {
b.leave();
    mhx = false;
}

function menu() {
var basemenu = window.CreatePopupMenu();
var contextman = fb.CreateContextMenuManager();
contextman.InitNowPlaying();

var child1 = window.CreatePopupMenu(); //File
var child2 = window.CreatePopupMenu(); //Edit
var child3 = window.CreatePopupMenu(); //View
var child4 = window.CreatePopupMenu(); //Playback
var child5 = window.CreatePopupMenu(); //Library
var child6 = window.CreatePopupMenu(); //Help
var child7 = window.CreatePopupMenu(); //Now playing
    var child8 = window.CreatePopupMenu(); //cherry test
    var child9 = window.CreatePopupMenu(); //apple test

var menuman1 = fb.CreateMainMenuManager();
var menuman2 = fb.CreateMainMenuManager();
var menuman3 = fb.CreateMainMenuManager();
var menuman4 = fb.CreateMainMenuManager();
var menuman5 = fb.CreateMainMenuManager();
var menuman6 = fb.CreateMainMenuManager();

// MF_STRING is defined in docs\flags.txt
child1.AppendTo(basemenu, MF_STRING, "File");
child2.AppendTo(basemenu, MF_STRING, "Edit");
child3.AppendTo(basemenu, MF_STRING, "View");
child4.AppendTo(basemenu, MF_STRING, "Playback");
child5.AppendTo(basemenu, MF_STRING, "Library");
child6.AppendTo(basemenu, MF_STRING, "Help");
child7.AppendTo(basemenu, MF_STRING, "Now Playing");
    basemenu.AppendMenuSeparator();
    child8.AppendTo(basemenu, MF_STRING, "CHERRY");
        child8.AppendMenuItem(MF_STRING, 7501, "cherries in my mouth [Console]");
        child8.AppendMenuItem(MF_STRING, 7502, "cherries in my hand [Open]");
    basemenu.AppendMenuItem(MF_STRING, 8000, "Preferences (Apple)");

menuman1.Init("file");
menuman2.Init("edit");
menuman3.Init("View");
menuman4.Init("playback");
menuman5.Init("library");
menuman6.Init("help");

menuman1.BuildMenu(child1, 1, 200);
menuman2.BuildMenu(child2, 201, 200);
menuman3.BuildMenu(child3, 401, 300);
menuman4.BuildMenu(child4, 601, 300);
menuman5.BuildMenu(child5, 901, 300);
menuman6.BuildMenu(child6, 1201, 100);

contextman.InitNowPlaying();
contextman.BuildMenu(child7, 1301, -100);
   
    var menuY = b.buttons.menu.h + b.buttons.menu.y + 4;
ret = basemenu.TrackPopupMenu(b.buttons.menu.x, menuY);

switch (true) {
case(ret >= 1 && ret < 201):
menuman1.ExecuteByID(ret - 1);
break;

case (ret >= 201 && ret < 401):
menuman2.ExecuteByID(ret - 201);
break;

case (ret >= 401 && ret < 601):
menuman3.ExecuteByID(ret - 401);
break;

case (ret >= 601 && ret < 901):
menuman4.ExecuteByID(ret - 601);
break;

case (ret >= 901 && ret < 1201):
menuman5.ExecuteByID(ret - 901);
break;

case (ret >= 1201 && ret < 1301):
menuman6.ExecuteByID(ret - 1201);
break;

case (ret >= 1301 && ret < 2000):     //case (ret >= 1301):
contextman.ExecuteByID(ret - 1301);
break;
       
    case (ret == 7501):
        fb.RunMainMenuCommand("View/Console");
        break;
    case (ret == 7502):
        fb.RunMainMenuCommand("File/Open...");
        break;
    case (ret == 8000):
        fb.RunMainMenuCommand("File/Preferences");
        break;
}

basemenu.Dispose();
contextman.Dispose();
menuman1.Dispose();
menuman2.Dispose();
menuman3.Dispose();
menuman4.Dispose();
menuman5.Dispose();
menuman6.Dispose();
}
<3