# HydrogenAudio

## Hosted Forums => foobar2000 => 3rd Party Plugins - (fb2k) => Topic started by: TheQwertiest on 2018-10-01 11:01:15

Title: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-10-01 11:01:15
Spider Monkey Panel     (https://img.shields.io/github/release/theqwertiest/foo_spider_monkey_panel.svg) (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/CHANGELOG.md) (https://ci.appveyor.com/api/projects/status/4fg787ijr73u7mxc/branch/master?svg=true) (https://ci.appveyor.com/project/TheQwertiest/foo-spider-monkey-panel/branch/master)

fb2k component that allows for creation of full-fledged CUI/DUI panels using JavaScript!

Base functionality includes:
- Graphics functions: drawing (text, images, lines, rectangles and etc), image modification (resize, blur, inversion of colours and etc).
- Capture of foobar2000 events with callbacks.
- Capture of keystrokes and mouse movement/clicks.
- Creation of custom buttons and menus.
- Playlist management: create, destroy, sort, change, rename and do anything that fb2k can do.
- Media Library access with ability to sort and filter it's content.
- File tag management.
- Per panel settings storage.
- Built-in web and filesystem functionality.
- foo_acfu (https://acfu.3dyd.com) integration.
- And more!

Getting started!
- Use Installation Guide (https://theqwertiest.github.io/foo_spider_monkey_panel/docs/installation).
- Check out Samples and User scripts (https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_showcase).
- Take a look at Documentation (https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation), if you are craving for more!

Information for JScript Panel users
Spoiler (click to show/hide)

- Homepage (https://theqwertiest.github.io/foo_spider_monkey_panel)
- Changelog (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/CHANGELOG.md)
- Detailed list of API Changes (https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/api_changes)
- Current tasks and plans (https://github.com/TheQwertiest/foo_spider_monkey_panel/projects/1)
- Dev build (https://ci.appveyor.com/api/projects/theqwertiest/foo-spider-monkey-panel/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel.fb2k-component?branch=master&job=Configuration%3A%20Release)

Credits
- marc2003 (https://github.com/marc2k3): original foo_jscript_panel (https://github.com/marc2k3/foo_jscript_panel), sample scripts (https://github.com/TheQwertiest/smp_2003) and multiple contributions to this project.
- T.P. Wang (https://hydrogenaud.io/index.php?action=profile;u=44175): original WSH Panel Mod (https://code.google.com/archive/p/foo-wsh-panel-mod).
- #jsapi IRC channel (https://wiki.mozilla.org/IRC): wouldn't make it through without them, love you guys!
Especially huge thanks to sfink and jonco, who spent literally tens of hours helping me!
- Respective authors (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/THIRD_PARTY_NOTICES.md) of the code being used in this project.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-01 11:15:34
Version: 1.0.0
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v100

Huge thanks to marc2003 (https://github.com/marc2k3) for porting samples and testing the component!
Title: Re: Spider Monkey Panel
Post by: seriousstas on 2018-10-02 21:24:31
Tried to see the cover:
foobar2000 \ user-components \ foo_spider_monkey_panel \ samples \ basic \ GetAlbumArtV2.txt

Code: [Select]
Error: Spider Monkey Panel v1.0.0 (GetAlbumArtV2 by T.P Wang)g_img.Dispose is not a functionFile: <main>Line: 35, Column: 3Stack trace:   on_playback_new_track @ <main>: 35: 3
https://hydrogenaud.io/index.php/topic,110938.0.html
Library tree ?
Title: Re: Spider Monkey Panel
Post by: WilB on 2018-10-03 00:51:55
Library Tree is in the process of being ported.
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-03 05:01:20
@TheQwertiest , I can't tell you how excited I am for this! Really want to check it out, but I need to finish my themes 1.0 release before I have to redo everything again :)

You said it's fast, but have you done performance benchmarking? What kind of speed increase are you seeing when initializing 10k files in your playlist component?

I saw this bit in the API docs:
Quote
utils.CreateHtmlWindow() method.
This method allows the creation of HTML windows rendered by IE8 engine.
utils.CreateHtmlWindow(html_code, { width: window_w, height: window_h, title: window_title, data: callback_data, fn: callback_fn }).
If that's using ActiveX to create the window, you can bump it up to IE11 using the FEATURE_BROWSER_EMULATION (https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)) registry key. Not ideal for sharing themes, but probably possible nonetheless.
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 09:32:06
@TheQwertiest , This is great work, at last an engine that has the latest ECMA support. Now I can use string.startsWith and array.findIndex. Heaven knows what I can do with those async functions!

Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-03 09:44:54
Tried to see the cover:
foobar2000 \ user-components \ foo_spider_monkey_panel \ samples \ basic \ GetAlbumArtV2.txt
Oops, forgot to nuke that Dispose call (will be fixed in v1.0.1).
For now you can just remove the following lines:
Code: [Select]
if (g_img)    g_img.Dispose();

https://hydrogenaud.io/index.php/topic,110938.0.html
Library tree ?
See @WilB 's reply above: it's being ported =)

Library Tree is in the process of being ported.
Nice! Looking forward to ;)
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 09:56:39
@TheQwertiest

I think I've found a problem. The following line;

gives this error;
handle argument is invalid
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-03 09:59:12
You said it's fast, but have you done performance benchmarking? What kind of speed increase are you seeing when initializing 10k files in your playlist component?
I was too lazy to perform any proper benchmarking. AFAIK most(?) operations are faster by at least an order of magnitude. There is one regression I've encountered though (https://bugzilla.mozilla.org/show_bug.cgi?id=1474914), so Playlist performance might be further increased by rewriting initialization without reverse.

you can bump it up to IE11 using the FEATURE_BROWSER_EMULATION (https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)) registry key. Not ideal for sharing themes, but probably possible nonetheless.
I'm in progress of total rewrite of CreateHtmlWindow, since current implementation has some nasty bugs (like fb2k lockup when user closes html window). As a side effect it should work properly with IE=edge and it will support loading htmls from file.

@TheQwertiest

I think I've found a problem. The following line;

gives this error;
handle argument is invalid
See https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/19

Bug will be fixed in v1.0.1
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 10:19:35
@TheQwertiest re issue #19
I've tried 'Build: 21:06:31, Oct  2 2018' patch from github and still get the same problem
Title: Re: Spider Monkey Panel
Post by: WilB on 2018-10-03 10:26:28
@Black_Over_Bills_Mothers
Quote

Yes, Biography, Library Tree & YouTube Track Manager are all in the process of being ported... Spider Monkey Panel is a really great advancement that will enable them to be used with the newer ECMA features. To implement these properly may take a little time, but hopefully they are not far away...
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-03 11:07:47
I'm just going to flat out make a request even before I RTFM...

Please, for the love of all that is, add an album rating method. Something similar to jsp_rating would be nice but I'm not that picky. That is the only feature left that I want in foobar and the one thing I miss about not using custom database. (Having custom notes in custom db was nice too but I can do that with a .txt)

And if not, because marc2003 wouldn't do it either when I asked, I'm still going to use this component because it looks great. Thanks for this.
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 12:16:03
Can we please have a better development environment. Links to an external editor such as Notepad++ or at least add text search and brace matching. I know you can export and import script but it's a pain.
Title: Re: Spider Monkey Panel
Post by: fbuser on 2018-10-03 14:53:11
Can we please have a better development environment. Links to an external editor such as Notepad++ or at least add text search and brace matching.
I'd consider this as a waste of time to implement such functionality. Just place one line like include('path/to/script.js') in the panel code area and do the code editing of this script with an editor of your choice.
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 15:10:25
Can we please have a better development environment. Links to an external editor such as Notepad++ or at least add text search and brace matching.
I'd consider this as a waste of time to implement such functionality. Just place one line like include('path/to/script.js') in the panel code area and do the code editing of this script with an editor of your choice.
Seems interesting but could you explain a little further please.
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-03 17:12:35
@Black_Over_Bills_Mothers
Quote

Yes, Biography, Library Tree & YouTube Track Manager are all in the process of being ported... Spider Monkey Panel is a really great advancement that will enable them to be used with the newer ECMA features. To implement these properly may take a little time, but hopefully they are not far away...
@WilB, great news!
looking forward to new versions of your cool scripts! (Don't forget JScript's version :) )
And I want to test Spider Monkey Panel
@TheQwertiest, thanks a lot for your great work!
Wish you creative success in the development of this project!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-03 20:42:39
I've tried 'Build: 21:06:31, Oct  2 2018' patch from github and still get the same problem
That's weird, I'll recheck later.

Wish you creative success in the development of this project!
Haha, thanks!

Please, for the love of all that is, add an album rating method. Something similar to jsp_rating would be nice but I'm not that picky.
Not sure what you mean. Do you want another custom metadb field? Like smp_album_rating?
PS: Both JSP and SMP provide a way to edit tags via UpdateFileInfoFromJSON.

Seems interesting but could you explain a little further please.
See docs/js_doc/Interfaces.js and samples. This method works like eval, but accepts path to file and provides better error-reporting.

On another note: JSP and SMP Configure window uses the same editor engine as Notepad++ =)
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-03 22:19:37
On another note: JSP and SMP Configure window uses the same editor engine as Notepad++ =)
Maybe he wants Atom :)
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-04 00:10:53
Maybe he wants Atom :)
Well, to be fair, only internal editor engines are the same, the engine wrappers are different, thus the different experience in Notepad++ compared to Configure window in JSP/SMP =)
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-04 01:04:24
Please, for the love of all that is, add an album rating method. Something similar to jsp_rating would be nice but I'm not that picky.
Not sure what you mean. Do you want another custom metadb field? Like smp_album_rating?
PS: Both JSP and SMP provide a way to edit tags via UpdateFileInfoFromJSON.
custom metadb field? Like smp_album_rating
^ That exactly.  I don't want to be changing the actual tags in the files. I realize I could do this in m-TAGS but that just creates other issues for me personally atm. Custom database was also really good for such things but it just got to the point it crashed so often it was unusable.
Again, Thanks for this component. It looks great.
Title: Re: Spider Monkey Panel
Post by: mjm716 on 2018-10-04 02:59:47
Maybe he wants Atom :)
Well, to be fair, only internal editor engines are the same, the engine wrappers are different, thus the different experience in Notepad++ compared to Configure window in JSP/SMP =)

"wordwrap" option would be nice! ;)

great job by the way!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-04 09:49:13
^ That exactly.  I don't want to be changing the actual tags in the files. I realize I could do this in m-TAGS but that just creates other issues for me personally atm. Custom database was also really good for such things but it just got to the point it crashed so often it was unusable.
Hm... Don't really want to add random tags. I'd rather make a generic method to add custom tags (well, if it's possible), smth like
Code: [Select]
utils.CreateCustomTag('smp_new_tag', 'number') ); // CreateCustomTag(tag_name, tag_type);...metadb.SetCustomTag('smp_new_tag', 'this is my tag value'); // SetCustomTag(tag_name, tag_value);

"wordwrap" option would be nice! ;)
Do you mean linewrap (when line is too big, part of it will move to the next line)?
If you do, then I can add in v1.0.1.
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-04 10:29:35
^ That exactly.  I don't want to be changing the actual tags in the files. I realize I could do this in m-TAGS but that just creates other issues for me personally atm. Custom database was also really good for such things but it just got to the point it crashed so often it was unusable.
Hm... Don't really want to add random tags. I'd rather make a generic method to add custom tags (well, if it's possible), smth like
Code: [Select]
utils.CreateCustomTag('smp_new_tag', 'number') ); // CreateCustomTag(tag_name, tag_type);...metadb.SetCustomTag('smp_new_tag', 'this is my tag value'); // SetCustomTag(tag_name, tag_value);
That would be fine. Great even. I could actually do more with that.
Title: Re: Spider Monkey Panel
Post by: mjm716 on 2018-10-04 11:08:00
Do you mean linewrap (when line is too big, part of it will move to the next line)?
If you do, then I can add in v1.0.1.

Notepad++ actually calls it wordwrap - but yes, linewrap option would be great!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-04 17:25:12
That would be fine. Great even. I could actually do more with that.
It seems that this is impossible... From fb2k SDK:
Quote
List of fields that you provide is expected to be fixed at run-time. The backend will enumerate your fields only once and refer to them by indexes later.
I.e. all fields must be defined when component loads and can't be added afterwards.
Another way might be to configure custom tags from the component's preferences page, but that would be possible only if component configuration is loaded before fields enumeration (which I doubt is the case).
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-04 20:41:39
You could add a customProperties field to the metadb and then expose some methods to store and read arbitrary JSON from it. It's kind of ugly and hacky, but since you're abstracting it away from the end-user it'd hide the ugly implementation details and be pretty seamless.

To be clear, I'm not really advocating this approach, but it's doable.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-05 11:48:23
Version: 1.0.1
Changelog
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v101
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-05 12:29:49
Version: 1.0.2
Changelog
Hotfix for v1.0.1 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg963027.html#msg963027))
Fixed
• Fixed regression in ActiveXObject handling.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-05 13:32:09
You said it's fast, but have you done performance benchmarking? What kind of speed increase are you seeing when initializing 10k files in your playlist component?
I've benchmarked playlist script a bit:
Playlist initialization speed is mostly the same. Profiling showed that bad performance of Array.reverse() is the main culprit. So it should greatly improve once I remove it.

But!!! I've noticed that CPU usage is halved during playlist scrolling!
- Normal scrolling: ~3.5% SMP vs ~7.5% JSP.
- Erratic scrolling in huge playlist: ~5% SMP vs ~10% JSP.

Another thing that I've noticed is that erratic scrolling in JSP has small hitches, while SMP does not suffer from it. Most likely caused by differences in GC management policy - JScript immediately destroys any resources that are no longer used, no matter how long it takes, while SpiderMonkey has a budget - it can spend only as much time in GC as allowed by budget.

Measured same performance increase during scrolling in @WilB 's Library Tree as well.

PS: I have a 6-core CPU and SMP/JSP are single-threaded, so to get a clearer picture results should be multiplied by six. Thus ~21% SMP vs ~45% JSP in normal scrolling and 30% SMP vs 60% JSP in erratic.
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-05 17:50:36
I noticed same interrupt of Shpeck visualization for both panels jsplaylist-mod script in JSP and SMP.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-06 12:57:54
I noticed same interrupt of Shpeck visualization for both panels jsplaylist-mod script in JSP and SMP.
What do you mean? Shpeck visualization is a separate component/panel and is not a part of SMP nor jsplaylist-mod :\
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-06 14:09:15
I noticed same interrupt of Shpeck visualization for both panels jsplaylist-mod script in JSP and SMP.
What do you mean? Shpeck visualization is a separate component/panel and is not a part of SMP nor jsplaylist-mod :\
Yes, but I mean these separate components (Shpeck and jsplaylist-mod) work at the same time in diferent CUI panels.
When together displaying the panel with Shpek and another panel with jsplaylist-mod, the visualization is displaying with jerks during a file playback.
This behavior of visualization when running jsplaylist-mod as in JSP or as in SMP is the same.
But when activated CUI Playlist view panel (jsplaylist-mod panel is not active), Shpeck visualization is displayed smoothly, without jerks.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-06 16:22:17
When together displaying the panel with Shpek and another panel with jsplaylist-mod, the visualization is displaying with jerks during a file playback.
Can't reproduce: Shpeck visualization(with MilkDrop2) is smooth with both stock CUI playlist and jsplaylist-mod script.
Possible cause of hitches you are experiencing: Shpeck is pretty CPU intensive, so, if your CPU is practically used up by Shpeck, then any additional CPU load might cause stuttering.

PS: I've tested jsplaylist-mod script a bit, and it does not seem to cause any meaningful CPU load during casual usage. And CPU load is close to nil when idle (i.e. when there is no interaction with playlist panel).
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-06 17:19:53
Did you test synchronous work the panels (Shpeck and jsplaylist-mod) during music playback? (triangle cursor of jsplaylist-mod should flashing)
Shpeck (with MilkDrop2) stuttering synchronous with flashing cursor. Shpeck works stable without playback.
Maybe it really depends on my hardware speed. Let's see maybe someone else will report of similar problem.
In any case, thanks for your time!
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-08 13:52:43
I have a script to automate the addition of new tracks/albums into my collection. This script calls fb.RunContextCommandWithMetadb function to remove all embedded images and then to Optimize and reduce file sizes - both core functionality. These two operations need to be performed sequentially. This has caused me two problems;
1) Firstly the call to fb.RunContextCommandWithMetadb does not block with means that the only way I can detect completeness is to catch the callback - okay but it would be better if the call could block - maybe optionally.
2) Both calls generate a popup window asking the user to click either close or OK button. Can this request be circumvented in some way?
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-09 17:36:09
Those are both built in functionality of foobar. There's nothing Spidermonkey or JScript can do to control those operations once it tells foobar to start them.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-11 10:17:01
Version: 1.0.3
Changelog
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v103

Note: v1.0.0 API changelog was missing description of on_notify_data callback behaviour change. It is rectified now: see wiki (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v100) or callbacks doc (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/component/docs/Callbacks.js).
Title: Re: Spider Monkey Panel
Post by: Decalicatan_Decalicatan on 2018-10-12 12:31:39
@TheQwertiest , thanks for the component

It seems there is an issue with the on_main_menu() function. As soon as I try to trigger one of the menu items, foobar2000 crashes :-(.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-12 14:26:03
@TheQwertiest , thanks for the component

It seems there is an issue with the on_main_menu() function. As soon as I try to trigger one of the menu items, foobar2000 crashes :-(.
Thanks for the report!
I'll look into it (#25 (https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/25)).
Title: Re: Spider Monkey Panel
Post by: Decalicatan_Decalicatan on 2018-10-14 21:56:21
@TheQwertiest you're welcome ^^.

I think I may have found another bug  O:) : using Columns UI and the "MainMenuManager All-In-One", as soon as I try to change to another layout --> instant crash...

Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-15 10:35:29
@TheQwertiest you're welcome ^^.

I think I may have found another bug  O:) : using Columns UI and the "MainMenuManager All-In-One", as soon as I try to change to another layout --> instant crash...
Could not reproduce the bug (on the latest build at least). Can you try the latest build (https://ci.appveyor.com/api/projects/theqwertiest/foo-spider-monkey-panel/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel.fb2k-component?branch=master&job=Configuration%3A%20Release)?
Title: Re: Spider Monkey Panel
Post by: Decalicatan_Decalicatan on 2018-10-15 17:26:24
My bad, I tried with a new portable installation and is fine. I think I may have messed up one of the js files in the "docs".

Anyway, on_main_menu() works fine now. Thanks!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-15 21:36:33
My bad, I tried with a new portable installation and is fine. I think I may have messed up one of the js files in the "docs".

Bug reproduced: see #29 (https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/29)
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-20 18:18:33
I have the following code in ratings.txt to set ratings using keyboard shortcuts:
Code: [Select]
// RATING HOTKEYSfunction on_main_menu(index) {	switch (index) {	case 1: // set rating File>Spider Monkey Panel>1 is run		panel.metadb.SetRating(panel.tf('$if2(%smp_rating%,0)') == 1 ? 0 : 1); panel.metadb.RefreshStats(); break; } } This, and every variation I have tried crashes foobar instantly. Now I'm assuming it's either something with my configuration or my code since I pretty much modified what I had in js_panel, but just in case it's something with spider monkey I thought I'd the thread aware this is happening. (Crash reports and full code attached if needed). Thanks. Title: Re: Spider Monkey Panel Post by: TheQwertiest on 2018-10-20 22:17:13 I have the following code in ratings.txt to set ratings using keyboard shortcuts: Code: [Select] // RATING HOTKEYSfunction on_main_menu(index) { switch (index) { case 1: // set rating File>Spider Monkey Panel>1 is run panel.metadb.SetRating(panel.tf('$if2(%smp_rating%,0)') == 1 ? 0 : 1);		panel.metadb.RefreshStats();		break;	} }

This, and every variation I have tried crashes foobar instantly. Now I'm assuming it's either something with my configuration or my code since I pretty much modified what I had in js_panel, but just in case it's something with spider monkey I thought I'd the thread aware this is happening. (Crash reports and full code attached if needed). Thanks.
Thanks for the report!
This is a known bug, which will be fixed in v1.0.4, which is expected to be released before the end of the next week.

PS: You can use the nightly build from the link in the OP for the time being. It should be noted though, that nightly build might be less stable than the release build and might have API incompatibilities, which are not documented. So it should be used only if you want to help me by testing it (thus making release-build more stable), or if you want to get your bug-fixes as soon as possible by accepting the risk of potential instability.
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-20 22:53:58
Ok great. Just making sure. I'll wait a few days for the stable as this is a minor issue for me and everything else seems to be working nicely.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-24 21:40:47
Version: 1.0.4
Changelog
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v104

Note: reset SMP advanced settings for better performance - Preferences>Advanced>Tools>Right-Click on Spider Monkey Panel>Reset Branch.

Huge thanks to @WilB for all the bug reports!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: loz on 2018-10-25 10:50:11
Fixed
• Fixed crash when on_main_menu callback was invoked.
Can confirm my issues with this have been fixed. Thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: embe on 2018-10-25 14:19:51
I'm having problem with displaying buttons with 'track info + seekbar + buttons' config. All I get are these rectangles. Do I need some special font installed for it?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-10-25 22:43:08
I'm having problem with displaying buttons with 'track info + seekbar + buttons' config. All I get are these rectangles. Do I need some special font installed for it?
That's because nobody reads Readme nowadays...

- "complete" scripts:
Should work fine on any system.
Most scripts require the installation of FontAwesome (https://github.com/FortAwesome/Font-Awesome/blob/fa-4/fonts/fontawesome-webfont.ttf?raw=true)."
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-05 21:04:14
Version: 1.0.5
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v105
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-19 19:08:10
Version: 1.1.0
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v110
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-20 11:49:00
Version: 1.1.1
Changelog
Hotfix for v1.1.0 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg965016.html#msg965016))
Fixed
• Fixed error in object constructor when it is invoked with data from on_notify_data callback.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AlexR on 2018-11-28 07:48:36
Do not work callback on_colours_changed()
version 1.1.1, foobar 1.4.1
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AlexR on 2018-11-28 11:29:39
Do not work callback on_colours_changed()
version 1.1.1, foobar 1.4.1, DUI
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-29 16:15:24
Do not work callback on_colours_changed()
version 1.1.1, foobar 1.4.1, DUI
Yep, that's a bug, will be fixed in the next version =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-09 11:01:17
Version: 1.1.2
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v112
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: SUPERCOOLMAN on 2019-01-13 01:33:37
trying to re-create an ancient foo_uie_albumart behaviour where pictures/arts in all user specified sub-directories of currently playing track are collected when track playback starts, then runs slideshow cycling through all the art every X second as specified by user

the component can load jpg, pg, bmp...etc. but not webp or other newer formats. I was wondering if it's possible for SMP to handle webp. maybe through some codec installed on the system?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-16 14:17:19
I was wondering if it's possible for SMP to handle webp. maybe through some codec installed on the system?
TLDR: SMP does not have functionality to load images that are not supported by fb2k.

SMP uses foobar2000 API to load album art and Gdiplus::Bitmap (https://docs.microsoft.com/en-us/windows/desktop/api/gdiplusheaders/nf-gdiplusheaders-bitmap-bitmap(inconstwchar_inbool)) to load external images. AFAIK neither fb2k nor GDI+ have the ability to work with webp files.
It's probably possible to write a fb2k component that can load webp files as images though (and maybe even work as album art source for fb2k).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-17 10:53:43
Version: 1.1.3
Changelog:
Spoiler (click to show/hide)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-01-19 18:21:25
I don't know if the issue is with the latest version (1.1.3) or if it was already there before, but I can't update ratings (foo_playcount) anymore with fb.RunContextCommandWithMetadb. For example with the rating.txt script. It does simple nothings :(

Thanks in advance. And ty for all the work you have already done with the component!
Regards
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-20 10:47:39
I am new to Spider Monkey Panel and J script panel.
I want to embed play back statistic information into the file.

Is there a function to edit metadata? (I only found retrieve info from metadata)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Rhand on 2019-01-20 11:28:36
This command doesn't work anymore with new spider panel.
buttons.buttons.albumart = new _button(bs * 6.8, 0, bs, bs, {normal : "Albumart.png", hover: "Albumart_h.png"}, function () { fb.RunContextCommand("Run service/AlbumArt"); },"AlbumArt"); Hope you can solve this
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-20 15:11:12
Version: 1.1.4
Changelog
Hotfix for v1.1.3 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg967258.html#msg967258))
Fixed
• Fixed fb.RunContextCommandWithMetadb not working with most commands.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-20 15:12:44
@Decalicatan_Decalicatan @Rhand : the issue should be fixed in v1.1.4. Thanks for the bug report!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-20 15:19:26
I am new to Spider Monkey Panel and J script panel.
I want to embed play back statistic information into the file.

Is there a function to edit metadata? (I only found retrieve info from metadata)
Depends on what you mean: you can't edit some most stats provided by foo_playcount (e.g. %play_count%), but you can write additional custom tags with FbMetadbHandleList.UpdateFileInfoFromJSON() (you can read more about the method and it's usage in the documentation included with component: Configure Panel dialog > menu > Help > View Help).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-01-20 16:25:18
@Decalicatan_Decalicatan @Rhand : the issue should be fixed in v1.1.4. Thanks for the bug report!

ty!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-21 02:36:39
Depends on what you mean: you can't edit some most stats provided by foo_playcount (e.g. %play_count%), but you can write additional custom tags with FbMetadbHandleList.UpdateFileInfoFromJSON() (you can read more about the method and it's usage in the documentation included with component: Configure Panel dialog > menu > Help > View Help).
Thank you, adding custom tags is the only thing I want.   ;)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-21 14:43:01
Version: 1.1.5
Changelog
Hotfix II for v1.1.3 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg967258.html#msg967258))
Changed
• Panel Properties dialog now uses JSON format by default for export.
Fixed
• Fixed incorrect parsing of UCS-2 LE encoded files.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-23 03:10:19
I want to find meta value(first value) by name.

According to the documentation.
I need to...
1. Check if there are matched name in the meta. if yes, go to step 2.
2. Find out how many meta in it.
3. Loop through the meta(s) to find the idx numbers for the name
4. Use the idx to get the Value out.

Is there any better way to doing this?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-23 09:06:46
I want to find meta value(first value) by name.

According to the documentation.
I need to...
1. Check if there are matched name in the meta. if yes, go to step 2.
2. Find out how many meta in it.
3. Loop through the meta(s) to find the idx numbers for the name
4. Use the idx to get the Value out.

Is there any better way to doing this?

There is also a MetaFind method, which returns the index of the meta field (or -1 if not found) =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-24 14:58:14
There is also a MetaFind method, which returns the index of the meta field (or -1 if not found) =)

Thank you it works.
I thought it only return like Boolean, I should read the documentation more carefully.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-06 16:53:34
First of all, a big thank you to @TheQwertiest for this component. I've been away from the forum for sometime and this is really a great surprise. It's good to have a jscript component back with official support and with the developer active in the forum. I'm following the migration instructions from JScript panel 2 and so far no problem. The only issue I found which was not mentioned in the official docs, nor in the forum, is that I can no more include both JScommon and Helpers in the preprocessor because some constants and variables are declared on both scripts.
I solved the problem by copying the few functions I actually needed, from JScommon to a new script, which replaced JScommon in the preprocessors where Helpers is also included. I like it better this way, it is definitely cleaner, but I just wanted to make sure that it is an intended behavior and I did not mess anything up.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-07 13:20:50
First of all, a big thank you to @TheQwertiest for this component.
You are very welcome :)

The only issue I found which was not mentioned in the official docs, nor in the forum, is that I can no more include both JScommon and Helpers in the preprocessor because some constants and variables are declared on both scripts.
Well, it was probably intended that way (that is for Br3tt's scripts to be self-sufficient).
I wouldn't know anyway, since I've never actually delved into them - it's only thanks to marc2003 that Br3tt's scripts were even included in SMP =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: anamorphic on 2019-02-08 05:00:59
I too, would like to heap many thanks upon TheQwertiest one for this component. I do believe it will be quite fun once I figure out how to write scripts. ;)

For now though I just have a minor, issue / question / request. (An issquesest?) If one (me) did not want to see the SMP Playback Statistics in track properties, how could one (I) turn display of them off? Might it please be possible? (We looked for options)

The thing is with 'Selection Properties' (DUI) element, all stats are lumped / jumbled together under 'Other' along with official Playback Statistics (foo_playcount) component. So I guess that is limitation of the element. However the original PS 'Rating' (displayed as stars) is gone altogether, replaced by SMP 'Rating' (with no stars, because not using it) - not very complementary. I'd prefer to see my original ratings.

(Of course, one could design a far superior 'Selection Properties' element with this very fine component. :D Even so... Edit: and I just found the 'properties.txt' sample after posting, typical!)

Cheers
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-08 10:54:29
I just noticed the stats show up twice in the properties tab. I still have JScript panel installed of course. It's not a problem, I just wonder why this happens:

Spoiler (click to show/hide)

Now, in the picture above you will also notice the custom database tags. I don't know how SMP statistics work, but if the values are pinned to primary tags or a combination of primary tags, like the official playback statistics component does, than this is potentially a custom database replacement. I've seen a previous request by @loz for custom tags, but I did not understand if they're planned to be implemented. Anyway I definitely second that request.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-08 21:02:31
Eventually I ran into a problem. I use some text files to share layout settings between jscript panels and panel stack splitter. I have a script which deletes a specific file when triggered, using the FileSystemObject DeleteFile method. It's a very simple script and it always worked with JScript Panel, but since migrating to Spider Monkey Panel the delete action is denied because the file is in use by foobar2000. I cannot even delete the file manually.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-09 12:19:02
For now though I just have a minor, issue / question / request. (An issquesest?) If one (me) did not want to see the SMP Playback Statistics in track properties, how could one (I) turn display of them off? Might it please be possible? (We looked for options)

The thing is with 'Selection Properties' (DUI) element, all stats are lumped / jumbled together under 'Other' along with official Playback Statistics (foo_playcount) component. So I guess that is limitation of the element. However the original PS 'Rating' (displayed as stars) is gone altogether, replaced by SMP 'Rating' (with no stars, because not using it) - not very complementary. I'd prefer to see my original ratings.
Not sure if I can do anything about it (apart from renaming the metatag, which I won't do :P).
@Peter : could you help us out, please? Is there a way to hide and/or reorder the priority of the metadata provided by components?

I just noticed the stats show up twice in the properties tab. I still have JScript panel installed of course. It's not a problem, I just wonder why this happens:
That is the intended behaviour: SMP and JSP use different (internal) tags to avoid potential compatibility issues.

I've seen a previous request by @loz for custom tags, but I did not understand if they're planned to be implemented. Anyway I definitely second that request.
This is something I'm planning to look into (that is the ability to add customs tags via SMP API), but it's rather low on my priority list.

Eventually I ran into a problem. I use some text files to share layout settings between jscript panels and panel stack splitter. I have a script which deletes a specific file when triggered, using the FileSystemObject DeleteFile method. It's a very simple script and it always worked with JScript Panel, but since migrating to Spider Monkey Panel the delete action is denied because the file is in use by foobar2000. I cannot even delete the file manually.
Could you provide the script (or it's relevant parts)?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-09 15:46:45
Eventually I ran into a problem. I use some text files to share layout settings between jscript panels and panel stack splitter. I have a script which deletes a specific file when triggered, using the FileSystemObject DeleteFile method. It's a very simple script and it always worked with JScript Panel, but since migrating to Spider Monkey Panel the delete action is denied because the file is in use by foobar2000. I cannot even delete the file manually.
Could you provide the script (or it's relevant parts)?

Sure, as I said it's a pretty simple one. The panel is resized via PSS (panel stack splitter) and this triggers either a delete or a create file action.
Code: [Select]
function on_size(){    switch (window.Height){        case 0:        if (fso.FileExists(SettingsPath + "PlaylistVisible")) fso.DeleteFile(SettingsPath + "PlaylistVisible");        RefreshPSS();        break;        case 1:        if (!fso.FileExists(SettingsPath + "PlaylistVisible")) fso.CreateTextFile(SettingsPath + "PlaylistVisible");        RefreshPSS();        break;           case 2:        if (fso.FileExists(SettingsPath + "PlaylistVisible")) fso.DeleteFile(SettingsPath + "PlaylistVisible");        RefreshPSS();        break;     }}

Here's also the relevant code from another script, included in the preprocessor:
Code: [Select]
var fso = new ActiveXObject("Scripting.FileSystemObject"); var SettingsPath = fb.ProfilePath + "settings\\";function RefreshPSS() {var Refresh_sys = window.GetProperty("Refresh_sys",true); if (Refresh_sys < true) {	if (fb.IsPlaying || fb.IsPaused) {  		fb.RunMainMenuCommand("View/Show status bar");		fb.RunMainMenuCommand("View/Show status bar");	} else {		fb.RunMainMenuCommand("View/Show status bar");		fb.RunMainMenuCommand("View/Show status bar");	}} else {	if (fb.IsPlaying || fb.IsPaused) {  		fb.RunMainMenuCommand("Playback/Play or Pause");		fb.RunMainMenuCommand("Playback/Play or Pause");	} else {		fb.RunMainMenuCommand("Playback/Play");		fb.RunMainMenuCommand("Playback/Stop");	}	}}

The script seems to work for a few times right after foobar2000 start up, but eventually something happens which blocks the file, and I can't figure out what it could even be.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-09 16:24:28
I just noticed the stats show up twice in the properties tab. I still have JScript panel installed of course. It's not a problem, I just wonder why this happens:
That is the intended behaviour: SMP and JSP use different (internal) tags to avoid potential compatibility issues.

I see, I never noticed before that JScript panel had its own! I though it was reading Spider Monkey Panel statistics.  :))
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-09 18:15:50
The script seems to work for a few times right after foobar2000 start up, but eventually something happens which blocks the file, and I can't figure out what it could even be.

TLDR: Use the following code fso.CreateTextFile(path).Close(); or let file = fso.CreateTextFile(path); file.Close();

Full story: the problem is caused by your usage of fso.CreateTextFile: CreateTextFile returns a file object, which contains an open handle to the file, which will be closed only in two cases - when object is destroyed and when it's closed manually. The lifetime of JS objects is variable, i.e. objects might not be immediately destroyed when there are no references to them, so in your case: object is alive & not closed > handle remains open > file remains locked.

PS: Plz, don't over-quote =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-09 20:32:18
TLDR: Use the following code fso.CreateTextFile(path).Close(); or let file = fso.CreateTextFile(path); file.Close();

Full story: the problem is caused by your usage of fso.CreateTextFile: CreateTextFile returns a file object, which contains an open handle to the file, which will be closed only in two cases - when object is destroyed and when it's closed manually. The lifetime of JS objects is variable, i.e. objects might not be immediately destroyed when there are no references to them, so in your case: object is alive & not closed > handle remains open > file remains locked.

Thanks, that was it. So, the real question is: why did it work with JScript panel?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-09 21:11:12
Thanks, that was it. So, the real question is: why did it work with JScript panel?
Because GC behaves differently in JScript and SMP (Microsoft's jscript is quite outdated in that way).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: WebSkater on 2019-02-12 13:59:01
Hi,
after installing Spider Monkey Panel in perfect working fb2k v1.3.20 on W7 x64 - and not making any use of it, i only installed it - I can't write rating tags to foo_playcount's database anymore. Modifying already existing rating tags stored in the database isn't possible either. Writing rating tags direct to files is still working. After uninstalling Spider Monkey Panel everything is working as before and writing and modifying rating tags in files or in the database is possible again without any issue !

Seems Spider Monkey Panel and the official Playback Statistics (foo_playcount) can't work together without making trouble.

Any ideas or suggestion?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-12 14:34:41
Replied on GitHub.

PS: please, do not duplicate bug reports in the future - posting it in one place (here or on GitHub) is good enough =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: WebSkater on 2019-02-12 17:28:08
Hi TheQwertiest,
sorry for duplicate posting, but I'm not very experienced in posting + "forum behaviour". Till now reading alone helped me over the years to solve my problems with foobar.

"Replied on GitHub"
means you noticed my post and are aware of the problem, but not that you have answered to it, right ? Stupid question, I know, but after "closing Github post by accident" and reopening and not seeing an answer after that in Github I'm really unsecure about this. Or I'm making something wrong again?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: michtar on 2019-02-13 13:01:46
I'm not sure if it's a system specific, user  :-[ , script or Spider Monkey Panel problem but:
- mouse-on and double click functions of "album art" sample stopped working. They used to work with SMP and work fine with JScript Panel.

- tested on clean portable install, Foobar 1.4.2, default components + Spider Monkey Panel 1.1.5, default path, Windows 7
- as far as I noticed script did not change
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-13 13:30:35
I'm not sure if it's a system specific, user  :-[ , script or Spider Monkey Panel problem but:
- mouse-on and double click functions of "album art" sample stopped working. They used to work with SMP and work fine with JScript Panel.

Thanks for the bug report! Will be fixed in the next version (kudos to marc2003).
In the mean time you can apply the fix manually - https://github.com/marc2k3/smp_2003/commit/c12b44f25fb5b810a7c92366e324191a2a0ce5bf
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: michtar on 2019-02-14 09:47:34
In the mean time you can apply the fix manually - https://github.com/marc2k3/smp_2003/commit/c12b44f25fb5b810a7c92366e324191a2a0ce5bf
Works (obviously). Thanks marc2003/TheQwertiest.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: dwmartin0906 on 2019-02-14 12:37:22
I was wondering if anyone else was having this problem with the SMP thumbs panel.  It works fine except when displaying the thumbs in a grid.  They display fine initially, but when clicking on a specific thumb to display it I get the following error.  Any ideas?

Error: Spider Monkey Panel v1.1.5 (Thumbs by marc2003)
_.drawOverlay is not a function

File: thumbs.js
Line: 100, Column: 5

Stack trace:
_thumbs/this.paint@thumbs.js:100:5
on_paint@<main>:58:2
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-15 09:09:00
I was wondering if anyone else was having this problem with the SMP thumbs panel.  It works fine except when displaying the thumbs in a grid.  They display fine initially, but when clicking on a specific thumb to display it I get the following error.  Any ideas?

Error: Spider Monkey Panel v1.1.5 (Thumbs by marc2003)
_.drawOverlay is not a function

File: thumbs.js
Line: 100, Column: 5

Stack trace:
_thumbs/this.paint@thumbs.js:100:5
on_paint@<main>:58:2
Yup, that's a bug =) Will be fixed in the next version (again kudos to marc2003).
In the mean time you can apply the fix manually - https://github.com/marc2k3/smp_2003/commit/a0e578ec06211b1d4b01f529962142bf50a75da5
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: dwmartin0906 on 2019-02-15 10:19:33
Thank you both very much.  That fixed it.  Amazing what one little period can do, isn't it?  I was a COBOL programmer for over 35 years so I understand how much damage one little typo can do.  At least you don't have to deal with hard copies, punch cards and 4 hour compile times like I had to in the beginning.  Debugging was a total nightmare.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-15 10:37:46
Yeah, script languages are quite convenient in that way (actually one of the reasons why WSH/JSP/SMP were developed in the first place).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-02-15 18:27:11
Hello!
Anybody knows if somebody already did a JS better than the default Album List DUI component?
The default Album List is "too slow" for me and many time starves.
I just need something providing a consolidated by folder structure view (as does Album List DUI) and some capability for searching the dBase by usual search patterns.
If I would be capable of programming in Java I would try myself, but I am not.
Thanks and regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: always.beta on 2019-02-16 00:31:56
Anybody knows if somebody already did a JS better than the default Album List DUI component?
https://hydrogenaud.io/index.php/topic,111060.0.html
Try it yourself
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-02-17 10:45:17
Hi Always.beta, many thanks!
Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-22 13:31:35
From what I gather, the strict mode defined in the panel does not apply to the scripts processed with the include statement. Is this an intended behaviour?
BTW, is the strict mode kind of mandatory with SMP or is it just a scrpting suggestion by the developers? or is it merely the common practice with the latest ECMA versions?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: philodoxxx on 2019-02-22 16:46:28
I have been experiencing an error on start up in Foobar related to the JS Smooth Browser sample script  in Spider Monkey Panel v1.1.5. See below:

Error: Spider Monkey Panel v1.1.5 (JS Smooth Browser by Br3tt aka Falstaff)
Resize failed:
Failed to create GdiPlus object (0x0: No error

File: jssb.js
Line: 3500, Column: 24

Stack trace:
get_images@jssb.js:3500:24
oBrowser/this.update@jssb.js:1526:3
oBrowser/this.setSize@jssb.js:1548:3
on_size@jssb.js:3120:3

If I reload the script it work's fine. The error only occurs at startup.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-23 23:41:55
So far I managed to upgrade all my scripts, but I still have a very old one by marc2003 that I can't get working on Spider Monkey Panel. The script is "Last.fm Album Art Downloader" with some little modifications I made over time and it still works perfectly on JScript Panel 2.1.4.

This is the script that works in JScript Panel:
Code: [Select]
// ==PREPROCESSOR==// @name "Last.fm Album Art Downloader"// @author "marc2003"// @import "%fb2k_component_path%samples\complete\js\lodash.min.js"// @import "%fb2k_component_path%samples\complete\js\helpers.js"// @import "%fb2k_component_path%samples\complete\js\panel.js"// ==/PREPROCESSOR==var SettingsPath = fb.ProfilePath + "settings\\";var library_tracks_only = false;var folder_tf = fb.TitleFormat("$puts(folder,$trim($replace($lower($directory(%path%)),disc,,cd,)))$replace($directory_path(%path%),$ifequal($strstr($get(folder),$num($get(folder),$len($get(folder)))),1,\\%directoryname%,),)\\");var filename_tf = fb.TitleFormat("front.jpg");var panel = new _.panel("Last.fm Album Art Downloader", ["metadb", "custom_background"]);var x = new ActiveXObject("Microsoft.XMLHTTP");var ini = SettingsPath + "album-art.ini";_.createFolder(SettingsPath);panel.item_focus_change();function on_metadb_changed() {	var np = fb.GetNowPlaying();	if (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))) {		var ar = panel.tf("%album artist%");		var al = panel.tf("%album%");		var f = folder_tf.EvalWithMetadb(panel.metadb) + _.fbSanitise(filename_tf.EvalWithMetadb(panel.metadb));		var tmp = _.q(_.fbSanitise(ar + al));		var n = _.round(_.now() / 1000);		var t = utils.ReadINI(ini, "Timestamps", tmp, 0);				switch (true) {		case !_.tagged(ar):		case !_.tagged(al):		case _.isFile(f):		case n - t < ONE_DAY:			break;		default:			utils.WriteINI(ini, "Timestamps", tmp, n);			x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true);			x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");			x.send();			x.onreadystatechange = function () {				if (x.readyState == 4) {					if (x.status == 200) {						var o = _.first(_.filter(_.getElementsByTagName(x.responsetext, "img"), {"className" : "image-list-image"}));						if (o) {							var u = o.src.replace("avatar170s", "ar0");							_.runCmd("cscript //nologo " + _.q(fb.ProfilePath + "scripts\\JSP\\download.vbs") + " " + _.q(u) + " " + _.q(f), false);							window.SetTimeout(function () {								panel.item_focus_change();							}, 3000);						}					} else {						console.log("HTTP error: " + x.status);					}				}			}            			break;		}	}	RefreshPSS();}function RefreshPSS() {var Refresh_sys = window.GetProperty("Refresh_sys",true); if (Refresh_sys < true) {	if (fb.IsPlaying || fb.IsPaused) {  		fb.RunMainMenuCommand("View/Show status bar");		fb.RunMainMenuCommand("View/Show status bar");	} else {		fb.RunMainMenuCommand("View/Show status bar");		fb.RunMainMenuCommand("View/Show status bar");	}} else {	if (fb.IsPlaying || fb.IsPaused) {  		fb.RunMainMenuCommand("Playback/Play or Pause");		fb.RunMainMenuCommand("Playback/Play or Pause");	} else {		fb.RunMainMenuCommand("Playback/Play");		fb.RunMainMenuCommand("Playback/Stop");	}	}}

...and this is my attempt to upgrade it for Spider Monkey Panel:
Code: [Select]
'use strict';window.DefinePanel('Last.fm Album Art Downloader', {author:'marc2003'});include(fb.ComponentPath + 'samples\\complete\\js\\lodash.min.js');include(fb.ComponentPath + 'samples\\complete\\js\\helpers.js')include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');var SettingsPath = fb.ProfilePath + "settings\\";var library_tracks_only = false;var folder_tf = fb.TitleFormat("$puts(folder,$trim($replace($lower($directory(%path%)),disc,,cd,)))$replace($directory_path(%path%),$ifequal($strstr($get(folder),$num($get(folder),$len($get(folder)))),1,\\%directoryname%,),)\\");var filename_tf = fb.TitleFormat("front.jpg");let panel = new _panel("Last.fm Album Art Downloader", ["metadb", "custom_background"]);var x = new ActiveXObject("Microsoft.XMLHTTP");var ini = SettingsPath + "album-art.ini";_createFolder(SettingsPath);panel.item_focus_change();function on_metadb_changed() {	var np = fb.GetNowPlaying();	if (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))) {		var ar = panel.tf("%album artist%");		var al = panel.tf("%album%");		var f = folder_tf.EvalWithMetadb(panel.metadb) + _fbSanitise(filename_tf.EvalWithMetadb(panel.metadb));		var tmp = _q(_fbSanitise(ar + al));		var n = _.round(_.now() / 1000);		var t = utils.ReadINI(ini, "Timestamps", tmp, 0);		switch (true) {		case !_tagged(ar):		case !_tagged(al):		case _isFile(f):		case n - t < ONE_DAY:			break;		default:			utils.WriteINI(ini, "Timestamps", tmp, n);			x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true);			x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");			x.send();			x.onreadystatechange = function () {				if (x.readyState == 4) {					if (x.status == 200) {						var o = _first(_filter(_getElementsByTagName(x.responsetext, "img"), {"className" : "image-list-image"}));						if (o) {							var u = o.src.replace("avatar170s", "ar0");							_runCmd("cscript //nologo " + _q(fb.ProfilePath + "scripts\\SMP\\download.vbs") + " " + _q(u) + " " + _q(f), false);							window.SetTimeout(function () {								panel.item_focus_change();							}, 3000);						}					} else {						console.log("HTTP error: " + x.status);					}				}			}			break;		}	}	RefreshPSS();}function RefreshPSS() {var Refresh_sys = window.GetProperty("Refresh_sys",true); if (Refresh_sys < true) {	if (fb.IsPlaying || fb.IsPaused) {  		fb.RunMainMenuCommand("View/Show status bar");		fb.RunMainMenuCommand("View/Show status bar");	} else {		fb.RunMainMenuCommand("View/Show status bar");		fb.RunMainMenuCommand("View/Show status bar");	}} else {	if (fb.IsPlaying || fb.IsPaused) {  		fb.RunMainMenuCommand("Playback/Play or Pause");		fb.RunMainMenuCommand("Playback/Play or Pause");	} else {		fb.RunMainMenuCommand("Playback/Play");		fb.RunMainMenuCommand("Playback/Stop");	}	}}

Unfortunately it doesn't crash, therefore I have no idea where the problem is, but it does not download the album cover (doubled checked with the JScript panel version).
Any insight will be much appreciated.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-02-24 15:31:12
@davideleo

Replace line 45 with

Code: [Select]
var o = _.first(_.filter(_getElementsByTagName(x.responseText, "img"), {"className" : "image-list-image"}));

_.first and _.filter are from lodash.js
_getElementsByTagName is from helpers.js

x.responseText is valid (not x.responsetext)

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-24 17:14:42
_.first and _.filter are from lodash.js
_getElementsByTagName is from helpers.js

x.responseText is valid (not x.responsetext)

Thanks so much @zeremy! I was going mad. It works now!
Why wouldn't SMP report an error, though?

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-02-24 17:26:59
Why wouldn't SMP report an error, though?

It is a known bug.

https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/Known-bugs
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-26 18:06:40
From what I gather, the strict mode defined in the panel does not apply to the scripts processed with the include statement. Is this an intended behaviour?
Not sure, gonna test it out with other JS engines to see how they handle it.

BTW, is the strict mode kind of mandatory with SMP or is it just a scrpting suggestion by the developers? or is it merely the common practice with the latest ECMA versions?
strict mode is not mandatory by any means, but it helps avoiding mistakes in the code (via stricter error checking) and might also increase it's performance. So, yes, it is a recommended mode of operation. You can read more about it >>here<< (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)

I have been experiencing an error on start up in Foobar related to the JS Smooth Browser sample script  in Spider Monkey Panel v1.1.5. See below:
Could you please try the Nightly build (see the link in the first post of this thread) and see if it produces a more intelligible error message?

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-27 21:30:31
Thanks so much @zeremy! I was going mad. It works now!

Seems like I spoke too soon. The script stopped working once again, but I can't tell if I got mistaken when I tested it or if I inadvertently made some changes in foobar2000 that affect SMP's behavior. Whatever is, I fixed it, but I still can't understand why SMP and JSP behave differently.

Here's the script as I'm usinig it now. The patch is marked by a comment:
Code: [Select]
var SettingsPath = fb.ProfilePath + "settings\\";var library_tracks_only = false;var folder_tf = fb.TitleFormat("$puts(folder,$trim($replace($lower($directory(%path%)),disc,,cd,)))$replace($directory_path(%path%),$ifequal($strstr($get(folder),$num($get(folder),$len($get(folder)))),1,\\%directoryname%,),)\\");var filename_tf = fb.TitleFormat("front.jpg");var panel = new _panel("Last.fm Album Art Downloader", ["metadb", "custom_background"]);var x = new ActiveXObject("Microsoft.XMLHTTP");var ini = SettingsPath + "album-art.ini";_createFolder(SettingsPath);panel.item_focus_change();function on_playback_new_track(){   //edit for Spider Monkey Panel	panel.item_focus_change();}function on_metadb_changed() {	var np = fb.GetNowPlaying();	console.log("SMP: metadb changed");	console.log("SMP: metadb_func = " + (typeof on_metadb_changed == 'function'));	console.log("SMP: if condition = " + (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))));	if (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))) {		var ar = panel.tf("$meta_sep(artist,', ',' and ')"); var al = panel.tf("%album%"); var f = folder_tf.EvalWithMetadb(panel.metadb) + _fbSanitise(filename_tf.EvalWithMetadb(panel.metadb)); var tmp = _q(_fbSanitise(ar + al)); var n = _.round(_.now() / 1000); var t = utils.ReadINI(ini, "Timestamps", tmp, 0); switch (true) { case !_tagged(ar): case !_tagged(al): case _isFile(f): case n - t < ONE_DAY: break; default: utils.WriteINI(ini, "Timestamps", tmp, n); x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true); x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT"); x.send(); x.onreadystatechange = function () { if (x.readyState == 4) { if (x.status == 200) { var o = _.first(_.filter(_getElementsByTagName(x.responseText, "img"), {"className" : "image-list-image"})); if (o) { var u = o.src.replace("avatar170s", "ar0"); _runCmd("cscript //nologo " + _q(fb.ProfilePath + "scripts\\SMP\\download.vbs") + " " + _q(u) + " " + _q(f), false); window.SetTimeout(function () { panel.item_focus_change(); }, 3000); } } else { console.log("HTTP error: " + x.status); } } } break; } } RefreshPSS();}function RefreshPSS() {var Refresh_sys = window.GetProperty("Refresh_sys",true); if (Refresh_sys < true) { if (fb.IsPlaying || fb.IsPaused) { fb.RunMainMenuCommand("View/Show status bar"); fb.RunMainMenuCommand("View/Show status bar"); } else { fb.RunMainMenuCommand("View/Show status bar"); fb.RunMainMenuCommand("View/Show status bar"); }} else { if (fb.IsPlaying || fb.IsPaused) { fb.RunMainMenuCommand("Playback/Play or Pause"); fb.RunMainMenuCommand("Playback/Play or Pause"); } else { fb.RunMainMenuCommand("Playback/Play"); fb.RunMainMenuCommand("Playback/Stop"); } }} From what I can understand of marc2003's original script, the code responsible for the download is all in the on_metadb_changed function, but because we want the code to be executed also when a new track is played, the on_metadb_changed function is invoked by the item_focus_change method of the panel object, on line 11. As far as I know this part of the code should be read only on panel start up, but with the console I was able to see that the item_focus_change method is executed on playback of a new track by JSP. So, is this one of those incorrect behaviors tolerated by JSP, but not by SMP? Or is the item_focus_change method triggered by some other event, I thought maybe it could be related to the built-in playcount, which is set differently by default in JSP and SMP? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2019-02-28 17:20:03 @davideleo The difference is that JSP panel.js is different from SMP panel.js Compare the two files and you will see that in JSP panel.js Code: [Select] function on_playback_new_track() { panel.item_focus_change();} is defined In SMP panel.js it is not defined Your edit added the missing function. TIL : When migrating a custom JSP script we should also check its include files. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-02-28 17:45:08 Compare the two files and you will see that in JSP panel.js Code: [Select] function on_playback_new_track() { panel.item_focus_change();} is defined In SMP panel.js it is not defined Your edit added the missing function. Can you please point me to the relevant code lines? I've been comparing the two panel.js versions for the last two days, but I couldn't find it. I must say the whole panel script is pretty hard for me to read, because of the many cross-references and the use of activex objects that I'm not familiar with. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2019-02-28 17:53:58 JSP https://github.com/marc2k3/foo_jscript_panel/blob/master/foo_jscript_panel/samples/complete/js/panel.js#L15 SMP https://github.com/marc2k3/smp_2003/blob/a0e578ec06211b1d4b01f529962142bf50a75da5/js/panel.js Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-02-28 18:03:40 JSP https://github.com/marc2k3/foo_jscript_panel/blob/master/foo_jscript_panel/samples/complete/js/panel.js#L15 SMP https://github.com/marc2k3/smp_2003/blob/a0e578ec06211b1d4b01f529962142bf50a75da5/js/panel.js OMG! I can't believe I totally ignored those callabacks :-[ I was concentrating on the panel object only. Thanks. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: philodoxxx on 2019-03-05 18:11:15 I have been experiencing an error on start up in Foobar related to the JS Smooth Browser sample script in Spider Monkey Panel v1.1.5. See below: Could you please try the Nightly build (see the link in the first post of this thread) and see if it produces a more intelligible error message? PS: @zeremy thanks for all the answers in this thread =) The error is pretty much the same with the nightly build: Error: Spider Monkey Panel v1.1.6-beta+0191969 (JS Smooth Browser by Br3tt aka Falstaff) Resize failed: Failed to create GdiPlus object (0X0): No error File: Line: 3500, Column: 24 Stack trace: get_images@:3500:24 oBrowser/this.update@:1526:3 oBrowser/this.setSize@:1548:3 on_size@:3120:3 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2019-03-05 19:28:42 @philodoxxx Try clearing the Panel Properties Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-06 11:13:03 The error is pretty much the same with the nightly build: Could you try again with the latest Nightly? It should produce a proper error message now. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2019-03-06 18:20:15 @TheQwertiest You can reproduce @philodoxxx error if you select Display > Album Art Grid Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-06 19:00:19 @TheQwertiest You can reproduce @philodoxxx error if you select Display > Album Art Grid Thanks! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-09 14:41:24 I noticed on one of my scripts that the on_paint() function always increases memory usage, without releasing it, until eventually foobar2000 has no alternative, but crash. I can't tell if this was happening before switching to SMP, because I never really analysed my scripts in this connection, but the flaw is likely in something I ignore about memory allocation and garbage collection. I'm posting here the on_paint() code, only, because the complete script is quite long, but if it helps I can post the rest of it. For reference: it's a playlist manager script. Code: [Select] function on_paint(gr) { var PlaylistVisible = (fso.FileExists(SettingsPath + "PlaylistVisible")); var MenuVisible = fso.FileExists(SettingsPath + "MenuVisible"); VisibleItemsCount = (wh / row_height); ScrollerHeight = Math.max(wh * VisibleItemsCount / UserPlaylistsCount, 30); ScrollerExtension = ScrollerHeight - (wh * VisibleItemsCount / UserPlaylistsCount); scrollbar_w = MenuVisible?17:0; idxStart = Math.max(idxStart, SysPlaylistsCount); idxEnd = Math.min(TotalPlaylistsCount, idxStart + Math.ceil(VisibleItemsCount)); var x = gr.CalcTextWidth(" ", font); var w = ww - x - scrollbar_w; var h = row_height; for (i = idxStart; i < idxEnd; i++) { var y = row_height*(i - idxStart); var MouseHover = (x <= mouse_x) && (mouse_x <= x + w) && (y <= mouse_y) && (mouse_y < y + h); var ActiveVisible = PlaylistVisible && plman.ActivePlaylist == i; var icon = plman.PlayingPlaylist == i && fb.IsPlaying?String.fromCharCode(57369):String.fromCharCode(57368); var text = " " + icon + (MenuVisible?" " + plman.GetPlaylistName(i):"") + (SHOW_COUNT?" [" + plman.PlaylistItemCount(i) + "]":""); var textColor = ActiveVisible?colours.White:offcolour; var bgColor = MouseHover?setAlpha(colours.Gray, 60):setAlpha(colours.Black, 0); if (!dragging && !scrolling) gr.FillSolidRect(x, y, w, h, bgColor); if (ActiveVisible) gr.FillSolidRect(x/2, y, x/2, h, RGBA(255,255,255,255)); gr.GdiDrawText(text, font, textColor, x, y, w, h, IFormat); if (dragging && MouseHover) gr.FillSolidRect(x, y + drag_down*row_height, w, 1, offcolour); } scrollbar_y = (idxStart - SysPlaylistsCount) * (wh - ScrollerExtension) / UserPlaylistsCount; gr.SetSmoothingMode(1); if (MenuVisible && (scrollbar || (SCROLLBAR_MODE == 0))) gr.FillRoundRect(ww - scrollbar_w, scrollbar_y, scrollbar_w, ScrollerHeight, 1, 1, RGBA(255,255,255,100)); gr.SetSmoothingMode(0); } Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-11 14:26:45 @philodoxxx Thanks for the bug report! It will be fixed in the next release, in the meantime you can apply the following fix manually - https://github.com/TheQwertiest/foo_spider_monkey_panel/pull/62/files I noticed on one of my scripts that the on_paint() function always increases memory usage, without releasing it... Doesn't look like there is anything that could cause a memory leak in your code. To diagnose the issue I need the full (i.e. working) sample. Ideally it should be stripped down as much as possible =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-11 14:29:34 [EDIT] Accidental double-post Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-11 18:08:11 To diagnose the issue I need the full (i.e. working) sample. Ideally it should be stripped down as much as possible =) If you mean the whole script, here it is: Code: [Select] 'use strict';window.DefinePanel('YouFy Playlist Manager', {author:'davideleo'});include(fb.ComponentPath + 'docs\\Flags.js');include(fb.ComponentPath + 'docs\\Helpers.js');include(fb.ProfilePath + 'scripts\\SMP\\YouFy common.js');var i = 0;var SysPlaylistsCount = 0;var UserPlaylistsCount = 0;var TotalPlaylistsCount = 0var idxStart = 0;var idxEnd = 0;var idxFrom = -1;var idxTo = -1;var mouse_x = -1;var mouse_y = -1;var dragging = false;var scrollbar = false;var scrolling = false;var SCROLLBAR_MODE = window.GetProperty("Scrollbar Mode", 2); //0=always, 1=never, 2=auto hidevar SHOW_COUNT = window.GetProperty("Show TrackCount", true);var row_height = Number(ReadSettingsValue("RowHeight", 45));var DPI = ReadSettingsValue("DPI", 96);var iconfont = ReadSettingsValue("iconfont","youfy mdl2 assets");var font_size = 16;var font_height = font_size * DPI / 72; var font = gdi.Font(iconfont, font_height, 0);var IFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX;count_playlists();function on_size() { ww = window.Width; wh = window.Height; }function on_paint(gr) { var PlaylistVisible = (fso.FileExists(SettingsPath + "PlaylistVisible")); var MenuVisible = fso.FileExists(SettingsPath + "MenuVisible"); VisibleItemsCount = (wh / row_height); ScrollerHeight = Math.max(wh * VisibleItemsCount / UserPlaylistsCount, 30); ScrollerExtension = ScrollerHeight - (wh * VisibleItemsCount / UserPlaylistsCount); scrollbar_w = MenuVisible?17:0; idxStart = Math.max(idxStart, SysPlaylistsCount); idxEnd = Math.min(TotalPlaylistsCount, idxStart + Math.ceil(VisibleItemsCount)); var x = gr.CalcTextWidth(" ", font); var w = ww - x - scrollbar_w; var h = row_height; for (i = idxStart; i < idxEnd; i++) { var y = row_height*(i - idxStart); var MouseHover = (x <= mouse_x) && (mouse_x <= x + w) && (y <= mouse_y) && (mouse_y < y + h); var ActiveVisible = PlaylistVisible && plman.ActivePlaylist == i; var icon = plman.PlayingPlaylist == i && fb.IsPlaying?String.fromCharCode(57369):String.fromCharCode(57368); var text = " " + icon + (MenuVisible?" " + plman.GetPlaylistName(i):"") + (SHOW_COUNT?" [" + plman.PlaylistItemCount(i) + "]":""); var textColor = ActiveVisible?colours.White:offcolour; var bgColor = MouseHover?setAlpha(colours.Gray, 60):setAlpha(colours.Black, 0); if (!dragging && !scrolling) gr.FillSolidRect(x, y, w, h, bgColor); if (ActiveVisible) gr.FillSolidRect(x/2, y, x/2, h, RGBA(255,255,255,255)); gr.GdiDrawText(text, font, textColor, x, y, w, h, IFormat); if (dragging && MouseHover) gr.FillSolidRect(x, y + drag_down*row_height, w, 1, offcolour); } scrollbar_y = (idxStart - SysPlaylistsCount) * (wh - ScrollerExtension) / UserPlaylistsCount; gr.SetSmoothingMode(1); if (MenuVisible && (scrollbar || (SCROLLBAR_MODE == 0))) gr.FillRoundRect(ww - scrollbar_w, scrollbar_y, scrollbar_w, ScrollerHeight, 1, 1, RGBA(255,255,255,100)); gr.SetSmoothingMode(0); }function on_mouse_move(x, y) { drag_down = y >= mouse_y; mouse_x = x; mouse_y = y; scrollbar = (UserPlaylistsCount > VisibleItemsCount && SCROLLBAR_MODE != 1); if(scrolling){ scrollbar_y = Math.max(exScrollbar_y + y - lbtn_down_y, 0); if(scrollbar_y + ScrollerHeight > wh) scrollbar_y = wh - ScrollerHeight; idxStart = Math.floor(scrollbar_y * UserPlaylistsCount / (wh - ScrollerExtension)) + SysPlaylistsCount; if(idxStart > TotalPlaylistsCount - VisibleItemsCount) idxStart = TotalPlaylistsCount - VisibleItemsCount; } window.Repaint(); } function on_mouse_lbtn_down(x, y){ if(x > ww - scrollbar_w) { if(y > scrollbar_y && y < scrollbar_y + ScrollerHeight) { exScrollbar_y = scrollbar_y; lbtn_down_y = y; scrolling = true; } else { if (y < scrollbar_y) idxStart = Math.max(idxStart - VisibleItemsCount,0); if (y > scrollbar_y + ScrollerHeight) idxStart = Math.min(idxStart + VisibleItemsCount, TotalPlaylistsCount - VisibleItemsCount); } } else { idxFrom = GetPlaylistIdx(y); plman.ActivePlaylist = idxFrom; fso.CreateTextFile(SettingsPath + "PlaylistVisible").Close(); if (plman.GetPlaylistName(plman.ActivePlaylist)){ WriteSettingsValue("ActivePlaylist",plman.GetPlaylistName(plman.ActivePlaylist)); WriteSettingsValue("PlaylistType",plman.IsAutoPlaylist(plman.ActivePlaylist)?"Autoplaylist":"Playlist"); } RefreshPSS(); dragging = true; mouse_y = y; } window.Repaint();}function on_mouse_leave() { mouse_x = -1; mouse_y = -1; scrollbar = false; window.Repaint();}function on_mouse_lbtn_up(x, y){ idxTo = GetPlaylistIdx(y); if (dragging) plman.MovePlaylist(idxFrom,idxTo); dragging = false; scrolling = false; window.Repaint(); RefreshPSS();}function on_mouse_lbtn_dblclk(x, y){ if(x < ww - scrollbar_w){ plman.PlayingPlaylist = GetPlaylistIdx(y); fb.Play(); window.Repaint(); }}function on_mouse_rbtn_down(x, y, mask){ var idx = GetPlaylistIdx(y); var ContextMenu = window.CreatePopupMenu(); var _ScrollbarOption = window.CreatePopupMenu(); ContextMenu.AppendMenuItem(MF_STRING, 1, "Rename..."); ContextMenu.AppendMenuItem(MF_STRING, 2, "Remove"); ContextMenu.AppendMenuItem(MF_STRING, 3, "Save..."); ContextMenu.AppendMenuItem(MF_STRING, 11, "Move to top"); ContextMenu.AppendMenuItem(MF_STRING, 12, "Move to bottom"); ContextMenu.AppendMenuSeparator(); if (plman.IsAutoPlaylist(idx)){ ContextMenu.AppendMenuItem(MF_STRING, 4, "AutoPlaylist Format"); ContextMenu.AppendMenuSeparator(); } ContextMenu.AppendMenuItem(MF_STRING, 5, "Show Track Count"); ContextMenu.CheckMenuItem(5, SHOW_COUNT?1:0); _ScrollbarOption.AppendTo(ContextMenu,0, "Show Scrollbar"); _ScrollbarOption.AppendMenuItem(MF_STRING, 6, "Always"); _ScrollbarOption.AppendMenuItem(MF_STRING, 7, "Never"); _ScrollbarOption.AppendMenuItem(MF_STRING, 8, "Auto Hide"); _ScrollbarOption.CheckMenuRadioItem(6,8,SCROLLBAR_MODE + 6); if (mask == 6||mask == 14){ ContextMenu.AppendMenuSeparator(); ContextMenu.AppendMenuItem(MF_STRING, 9, "Properties"); ContextMenu.AppendMenuItem(MF_STRING, 10, "Configure..."); } if(idx != null){ switch(ContextMenu.TrackPopupMenu(x, y, 0)){ case 1: plman.ActivePlaylist = idx; fb.RunMainMenuCommand("File/Rename Playlist") ; break; case 2: plman.RemovePlaylist(idx); UserPlaylistsCount = TotalPlaylistsCount - SysPlaylistsCount; plman.ActivePlaylist = Math.min(idx, UserPlaylistsCount - 1); window.Repaint(); break; case 3: plman.ActivePlaylist = idx; fb.SavePlaylist(); break; case 4: plman.ShowAutoPlaylistUI(idx); break; case 5: SHOW_COUNT = !SHOW_COUNT; window.SetProperty("Show TrackCount", SHOW_COUNT); ContextMenu.CheckMenuItem(5, SHOW_COUNT); window.Repaint(); break; case 6: SCROLLBAR_MODE = 0; window.SetProperty("Scrollbar Mode", 0); _ScrollbarOption.CheckMenuRadioItem(6,8,6); break; case 7: SCROLLBAR_MODE = 1; window.SetProperty("Scrollbar Mode", 1); _ScrollbarOption.CheckMenuRadioItem(6,8,7); break; case 8: SCROLLBAR_MODE = 2; window.SetProperty("Scrollbar Mode", 2); _ScrollbarOption.CheckMenuRadioItem(6,8,8); break; case 9: window.ShowProperties() break; case 10: window.ShowConfigure(); break; case 11: plman.MovePlaylist(idx, SysPlaylistsCount); window.Repaint(); break; case 12: plman.MovePlaylist(idx, TotalPlaylistsCount - 1); window.Repaint(); break; default: break; } }}function on_drag_over(action, x, y, mask){ mouse_x = x; mouse_y = y; window.Repaint(); }function on_drag_drop(action, x, y) { var idx = GetPlaylistIdx(y); action.Playlist = idx; action.ToSelect = false; plman.ActivePlaylist = idx;}function on_playlists_changed() { count_playlists(); window.Repaint();}function on_notify_data(name, info) { switch(name) { case "refresh": window.Repaint(); RefreshPSS(); break; case "row height": row_height = info; window.Repaint(); break; }}function GetPlaylistIdx(y) { return Math.floor(y / row_height) + idxStart;}function count_playlists(){ //system playlists are prefixed with a "#" and must be hidden from the playlist manager. TotalPlaylistsCount = plman.PlaylistCount; SysPlaylistsCount = 0; for (i = 0; i < TotalPlaylistsCount; i++) { if (plman.GetPlaylistName(i).search("#") == 0) { if (i > SysPlaylistsCount) plman.MovePlaylist(i, SysPlaylistsCount); SysPlaylistsCount = SysPlaylistsCount + 1; } } UserPlaylistsCount = TotalPlaylistsCount - SysPlaylistsCount;} If you really are willing to review my script (in which case I'd be eternally grateful), for completeness here's also the preprocessed "YouFy common" script: Code: [Select] // *****************************************************************************************************************************************// Additional functions & flags for the YouFy skin// *****************************************************************************************************************************************var fso = new ActiveXObject("Scripting.FileSystemObject"); var SettingsPath = fb.ProfilePath + "settings\\";var SkinPath = fb.ProfilePath + "skins\\YouFy\\";var ImagesPath = fb.TitleFormat("%images_path%").Eval(true) + "\\";var ThumbsPath = ImagesPath + "thumbs\\";var BackgroundPath = ImagesPath + "background\\";var offcolour = RGB(120,120,120);function ReadSettingsValue(folder,default_value) { if (!fso.FolderExists(SettingsPath)) fso.CreateFolder(SettingsPath); var FolderPath = SettingsPath + folder +"\\"; if(!fso.FolderExists(FolderPath)) { WriteSettingsValue(folder,default_value); return default_value; } else { var FolderObj = fso.GetFolder(FolderPath); var FolderEnumerator = new Enumerator(FolderObj.Files); if(fso.FileExists(FolderEnumerator.item(1))) { return FolderEnumerator.item(1).Name; } else { WriteSettingsValue(folder,default_value); return default_value } }}function WriteSettingsValue(folder,value) { if (!fso.FolderExists(SettingsPath)) fso.CreateFolder(SettingsPath); var FolderPath = SettingsPath + folder; if(fso.FolderExists(FolderPath)) { var FolderObj = fso.GetFolder(FolderPath); var FolderEnumerator = new Enumerator(FolderObj.Files); for (var i = 1; i < FolderObj.Files.Count + 1; i++) { fso.DeleteFile(FolderEnumerator.item(i)); } } else { fso.CreateFolder(FolderPath); } fso.CreateTextFile(FolderPath + "\\" + value).Close();} function RefreshPSS() {var Refresh_sys = window.GetProperty("Refresh_sys",true); if (Refresh_sys < true) { if (fb.IsPlaying || fb.IsPaused) { fb.RunMainMenuCommand("View/Show status bar"); fb.RunMainMenuCommand("View/Show status bar"); } else { fb.RunMainMenuCommand("View/Show status bar"); fb.RunMainMenuCommand("View/Show status bar"); }} else { if (fb.IsPlaying || fb.IsPaused) { fb.RunMainMenuCommand("Playback/Play or Pause"); fb.RunMainMenuCommand("Playback/Play or Pause"); } else { fb.RunMainMenuCommand("Playback/Play"); fb.RunMainMenuCommand("Playback/Stop"); } }}function Get_taskbar_colour() { var Shell = new ActiveXObject("WScript.Shell"); if (Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\\ColourPrevalence")) { if (Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\\EnableTransparency")) { return AccentPalette(7); } else { return AccentPalette(6); } } else { if (Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\\EnableTransparency")) { return "0-0-0"; } else { return "16-16-16"; } }}function AccentPalette(item) { var Shell = new ActiveXObject("WScript.Shell"); item = item -1; AccentPaletteArray = Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent\\AccentPalette");// return AccentPaletteArray[4*item] + "-" + AccentPaletteArray[1+4*item] + "-" + AccentPaletteArray[2+4*item]; return RGB(AccentPaletteArray[4*item], AccentPaletteArray[1+4*item], AccentPaletteArray[2+4*item]);}function Get_dpi() { var Shell = new ActiveXObject("WScript.Shell"); return Shell.RegRead("HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics\\AppliedDPI");}var library_items = fb.GetLibraryItems();function list_values(tag, handle_list = library_items, query = tag + " PRESENT", split = true){ var tags = []; var items = fb.GetQueryItems(handle_list, query) for (var i = 0; i < items.Count; i++) { var handle = items[i]; var meta_num = fb.TitleFormat("$meta_num(" + tag + ")").EvalWithMetadb(handle);		for (var j = 0; j < meta_num; j++) {			tags.push(fb.TitleFormat("$meta(" + tag + "," + j + ")").EvalWithMetadb(handle)); } } fb.ShowPopupMessage(_.uniq(tags.sort(), true).join("\n"));} All in all the script works fluently and the on_paint routine doesn't actually use much memory. What leaves me perplexed is that it is never released. Why would that even happen, unless something's not working properly with the GC? P.S. I also wanted to explain that I realized the issue was with the on_paint function because the on_mouse_move function always triggers a repaint. By simply moving the mouse over the panel, the memory increases. After commenting out the repaint instruction, moving the mouse over the panel doesn't increase memory usage by one byte. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-11 19:47:51 I also wanted to explain that I realized the issue was with the on_paint function because the on_mouse_move function always triggers a repaint. By simply moving the mouse over the panel, the memory increases. After commenting out the repaint instruction, moving the mouse over the panel doesn't increase memory usage by one byte. I uploaded a short video (https://www.dropbox.com/s/p1yrvbnytaq5b66/2019-03-11%2020-30-51.mp4?dl=0) to show what I mean (and maybe it is also of help to who is willing to take a look at my script). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: philodoxxx on 2019-03-11 20:39:49 @philodoxxx Thanks for the bug report! It will be fixed in the next release, in the meantime you can apply the following fix manually - https://github.com/TheQwertiest/foo_spider_monkey_panel/pull/62/files Thank you. Switching out those few lines in the script did indeed fix the issue. Regards. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-12 10:24:50 @davideleo your script looks like this for me Spoiler (click to show/hide) And there were no apparent memory leaks :\ Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-12 13:41:22 @davideleo your script looks like this for me Yes, that's because you are missing the "Youfy MDL2 assets" font, which is a collage-font I put together for this skin. Actually there are also a few variables which take their value from text files created by another script. And there were no apparent memory leaks :\ So, that's a clue, isn't it? Doesn't it close in on the interaction with other scripts or components? I actually already tested it without the black sheep of foobar2000's plug-ins, foo_customdb, but nothing changed. What about the GC settings in the advanced preferences? Should I mess around with them? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-12 16:02:38 I tested all of my scripts and it turned out it's a general problem. Every on_paint() function seems to increase memory and never release it. Even worse is that there is likely an on_playback_newtrack() function with the same problem, but I still didn't find out which one. That means my foobar2000 is bound to crash sooner or later at every session, even if I don't touch it. What really put me down is that I also tested the only script I have by another author (marc2003's Last.fm Bio) and guess what? No memory leak at all. This is the proof that the problem is in my scripting. @TheQwertiest when you write that there were no apparent memory leaks, do you mean that triggering the on_mouse_move() doesn't increase memory usage or that the memory increase is then released? BTW thanks a lot for taking a look. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: juniiflow on 2019-03-13 10:14:47 Anyone knows a quick way to remove or move the now playing arrow on j smooth? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Strigoy on 2019-03-13 12:58:06 Uh, this 'Edit' menu problem drives me nuts )) I don't get it, why this happens (this only affects 'Edit' submenu, others work just fine): (https://i.imgur.com/7NQBTxp.png) but if I use default Menu everything works just fine => (https://i.imgur.com/fnDOzg7.png) I'm using snippet from MainMenuManager All-In-One.js Speaking of which: I got couple of questions: 1) Code: [Select] contextman.InitNowPlaying();  this is getting called twice for some reason 2) Am I MisSinG SoMetHing wItH thE CasE herE? Code: [Select]  menuman1.Init('file'); menuman2.Init('edit'); menuman3.Init('View'); menuman4.Init('playback'); menuman5.Init('library'); menuman6.Init('help'); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Strigoy on 2019-03-13 21:54:14 Nevermind, guh... I've spent so much time trying to figure it out, but the problem was with panel settings... just unchecked 'grab focus' and it's working as intended. My god, that's so silly... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-14 12:25:39 Uh, this 'Edit' menu problem drives me nuts )) I don't get it, why this happens (this only affects 'Edit' submenu, others work just fine): Not sure what's going on here - it works fine for me (both with Grab Focus enabled and disabled). 1) this is getting called twice for some reason 2) Am I MisSinG SoMetHing wItH thE CasE herE? Because reasons :D Those are just typos. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-14 16:40:17 @davideleo your script looks like this for me Spoiler (click to show/hide) And there were no apparent memory leaks :\ I tested my script on a clean installation with no other plug-in, but spider monkey panel. The memory leak was more than apparent. How did you test it? I really need to get to the bottom of this problem, because it is making spider monkey panel unusable for me. P.S. BTW, on a clean installation I realized that the reason for that appearance is that the script does not find the "MenuVisible" file (without extension) in the "settings" folder inside the foobar2000 configuration folder. It is normally created by another script. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-14 18:12:21 P.P.S. I tested some of the sample scripts to see if I could find at least one with a similar behaviour. Eventually I found that the "track info + seekbar + buttons" by marc2003 increases memory usage by 0,8-9 MB at every button click without releasing it, but it looks like marc2003 managed the issue, because it is released when (and apparently only if) the total memory delta is around 20MB. EDIT I made a mistake: it's not the button click that increases memory, but the playback state change, triggered by the button click. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-14 23:58:52 I made some steps forward in my inquiry on the memory-greedy script. First of all I realized that memory usage increases only when several repaint actions are executed sequentially at close intervals, therefore I managed to lessen its impact by limiting the repaint action to when it is actually required, rather than on any on_mouse_move event. That didn't solve the issue, though, and if I move the mouse very quickly, over the panel, I can still reproduce it, even if it takes longer to reach dangerous levels. Anyway, I finally tested the same script on a JScript panel, on the same clean installation of the Spider Monkey panel. Here (https://www.dropbox.com/s/0yci9nfctu70cx6/2019-03-14%2023-38-45.mp4?dl=0)'s what happened (yes, I know I look like a weirdo). I moved the mouse up and down on the JScript panel for about one minute and - as you can see in the task manager - the memory level is stuck on 677,2 MB. There is only a slight increase towards the end, released right after. The same action on the Spider Monkey panel immediately starts raising the memory in use and after one minute it's well over 680 MB. Sorry if I sound obsessed, but since I'm still learning javascript, it's very important for me to understand what I didn't get right, before I move on to more advanced scripting. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-15 09:08:25 but it looks like marc2003 managed the issue, because it is released when (and apparently only if) the total memory delta is around 20MB. That's just GC kicking in - it has several triggers, one of which is the amount of allocated memory. I.e. you don't have to Dispose anything manually in 99.9% cases in SMP. What about the GC settings in the advanced preferences? Should I mess around with them? You should not =) when you write that there were no apparent memory leaks, do you mean that triggering the on_mouse_move() doesn't increase memory usage or that the memory increase is then released? BTW thanks a lot for taking a look. The memory increase is minuscule and it's not permanent - it's cleaned up properly after sometime with GC (i.e. it's not a leak). [EDIT] Can you download the debug version of SMP and enable GC zeal and check if memory is still leaking for you? Debug version: https://ci.appveyor.com/api/buildjobs/rylakh87w1kuotm2/artifacts/_result%2FWin32_Debug%2Ffoo_spider_monkey_panel.fb2k-component_debug GC Zeal: Preferences > Advanced > Display > Spider Monkey Panel > GC > Zeal > Enable Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-15 12:59:12 @davideleo you can also try the latest Nightly build (which is available via link in OP) - I might have fixed the leak there. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-15 14:11:18 With the nightly build (1.1.6-beta+80ac164) the behavior is unchanged and when I try installing the debug version I get this message: Quote Failed to load DLL: foo_spider_monkey_panel.dll Reason: This component is missing a required dependency, or was made for different version of foobar2000. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-15 15:53:14 With the nightly build (1.1.6-beta+80ac164) the behavior is unchanged... I think it was not the latest version. Anyway I just tried 1.1.6-beta+f3d6584 and it behaves in the same way. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-15 15:54:10 With the nightly build (1.1.6-beta+80ac164) the behavior is unchanged Are you sure? Note that GC does not kick in immediately, that is 10mb of allocated memory is not enough to trigger GC. Try reaching 100mb of allocations. This component is missing a required dependency, or was made for different version of foobar2000 I will send you a PM with missing dlls later this evening or tomorrow. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-15 20:25:07 Are you sure? Note that GC does not kick in immediately, that is 10mb of allocated memory is not enough to trigger GC. Try reaching 100mb of allocations. You are right! I gave the job to a timer, set to execute the repaint action once every millisecond. Right after startup, foobar2000 was using 677MB. After about 7 minutes the GC kicked in and memory usage dropped from 825MB to 690MB. I didn't clear the timer the first time and watched it repeat the cycle with the exact same values. Just to make sure I tested the release version, too, and to my surprise it performed even better, dropping from 820MB to 687MB. That's quite encouraging, even though I don't really understand why a script like mine would use so much memory for what to me looks basically like reassigning already allocated variables. I will send you a PM with missing dlls later this evening or tomorrow. Thanks a lot, I really appreciate your attention. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-16 12:06:53 I don't really understand why a script like mine would use so much memory for what to me looks basically like reassigning already allocated variables GC is tuned for the best performance with multiple active SMP panels and heavy-allocating scripts, so it might be not aggressive enough for simple (that is light-allocating) scripts. That said, your case helped me to discover a bug, which made GC to be more lenient with memory allocation than it should've been. You can check out the fix with the latest Nightly build =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-16 17:10:51 You can check out the fix with the latest Nightly build =) I just tested the script with beta version 2fdc8be and it behaves similarly, perhaps slightly worst: GC kicked in at 835MB (higher threshold than beta f3d6584) and dropped to 694MB (higher residual than beta f3d6584). The fact remains that with JScript panel the same script does not raise memory usage at all. I recorded one more video (https://www.dropbox.com/s/p6fn2aj9odp7bcb/2019-03-16%2017-04-44.mp4?dl=0) which shows the task manager while two identical foobar2000 installations run the same script, one with JScript panel and one with Spider Monkey panel. The timer is set on start-up, and the two installations are launched simultaneously. Mind that no dispose() method was added in the JScript panel version. GC is tuned for the best performance with multiple active SMP panels and heavy-allocating scripts, so it might be not aggressive enough for simple (that is light-allocating) scripts. I'm a bit puzzled now: is JScript panel better tuned for light-allocating scripts? Is it more advisable for simple ones like mine? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-17 22:39:09 I just tested the script with beta version 2fdc8be and it behaves similarly Hm... That's weird... I'm currently reworking GC a bit, so hopefully the memory usage will go down with next builds. The fact remains that with JScript panel the same script does not raise memory usage at all. Because JSP does not have GC at all, which has it advantages like never using more memory than currently needed, but at the cost of the performance. See the following post for a bit more info and performance trade-off example: https://hydrogenaud.io/index.php/topic,116669.msg963036.html#msg963036 I'm a bit puzzled now: is JScript panel better tuned for light-allocating scripts? Is it more advisable for simple ones like mine? I've never said anything like that. SMP and JSP are different beasts with different memory allocation policies. SMP uses (generally) more memory than JSP, but provides enhanced performance and smoother UX instead. What I did say, is that I tuned SMP GC policies for more heavy scripts. So, while it uses more memory with light scripts than it could've (i.e. it would accumulate more memory before purging it), it consumes CPU time drastically less with heavy scripts than it would've otherwise (which results in smoother UX and etc and etc). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-18 20:59:57 I've never said anything like that. SMP and JSP are different beasts with different memory allocation policies. SMP uses (generally) more memory than JSP, but provides enhanced performance and smoother UX instead. What I did say, is that I tuned SMP GC policies for more heavy scripts. So, while it uses more memory with light scripts than it could've (i.e. it would accumulate more memory before purging it), it costumes CPU time drastically less with heavy scripts than it would've otherwise (which results in smoother UX and etc and etc). I see, that makes sense, thanks for the explanation. I couldn't quite relate it to what I's experiencing because other heavy-looking scripts by professional coders didn't increase memory usage as much and my fear was that I was ignoring some basic good practice in my scripts. Eventually I found at least one professional script with a much bigger impact on memory and that reassured me a bit. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-19 15:01:43 @davideleo Please try the latest build again. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-20 14:34:04 I'm testing beta 6cc1cbd. The memory increases at a similar pace than the previous ones, but apparently GC comes round more often and with a smaller truck. With foobar2000 starting up at 670-680 MB, beta 2fdc8be and the stable release both need at least 825-835 MB (but today it was 850-860 MB, just to make things more random!) before dropping to more or less 700 MB. Beta 6cc1cbd drops from 800-810 MB to 760 MB. My two cents: by looking at the first cycle only, it would seem a lot better. I wonder, though, whether a higher garbage residual means that, on the long run, the average memory usage is bound to increase more rapidly. What is also hard to tell is how multiple panels, working together in a real usage set up, would actually perform: analytically speaking the single panel is better off with a lower peak, but a higher residual means that the overall uncollected garbage level is generally higher. So, except for the very rare case of all scripts approaching their memory cap at the same time, I can't tell really which one is more advisable. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-20 15:53:02 With foobar2000 starting up at 670-680 MB, beta 2fdc8be and the stable release both need at least 825-835 MB (but today it was 850-860 MB, just to make things more random!) before dropping to more or less 700 MB. Beta 6cc1cbd drops from 800-810 MB to 760 MB. Mind though, that you should differentiate between total memory usage (i.e. via task manager) and SMP memory usage (via window.TotalMemoryUsage). What is also hard to tell is how multiple panels, working together in a real usage set up, would actually perform: analytically speaking the single panel is better off with a lower peak, but a higher residual means that the overall uncollected garbage level is generally higher Whatever the case it should not leak anymore. That is, SMP average memory usage should stay mostly the same. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-20 20:37:40 Whatever the case it should not leak anymore. That is, SMP average memory usage should stay mostly the same. I monitored the memory values for over 2 hours (not literally, I recorded 2 hours of task manager and then scrolled the frames through) because I was curious of the GC behavior on the long run, so now I have a bigger picture. The new beta stabilizes already after the first GC action, whereas the previous beta and the stable release keep on raising the baseline - and to a lesser extent the peak level - for over one hour! That's a long time and if you don't know it will come to an end, it really looks like a bad memory leak. The comparison I made above did not take this into account: I compared the stabilized memory baseline of the new beta with the still growing baseline of the other two. Once the values are stable, the winner is the new beta by all means. Mind though, that you should differentiate between total memory usage (i.e. via task manager) and SMP memory usage (via window.TotalMemoryUsage). You shouldn't have told me. Now I know what I'll do in the next days. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-20 20:46:39 And now for something completely different: is it possible to read and edit the search pattern of an autoplaylist via JScript? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-03-21 09:17:26 And now for something completely different: is it possible to read and edit the search pattern of an autoplaylist via JScript? Yep :) plman.ShowAutoPlaylistUI(pl_idx); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-03-21 14:57:29 Yep :) plman.ShowAutoPlaylistUI(pl_idx); As far as I know that opens the autoplaylist properties dialog window. I want to read (and possibly edit) the query pattern by code. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-03-21 15:26:19 And now for something completely different: is it possible to read and edit the search pattern of an autoplaylist via JScript? fb2k does not provide such API, so neither SMP nor JSP have this feature. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-03 17:12:29 I apologize for the lack of updates (and the promised fixes), so here is a bit info to those who care(^^): Recently my motivation suffered a huge blow from Mozilla and it's shenanigans, which (coupled with my usual lack of free time) mostly stalled any progress on the next SMP release. Hopefully, the motivation will restore itself (at least partially) soon enough, but it may take some time... Regardless, the current SMP version (and the nightly build as well) should be stable enough to last till the new release =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-04-03 18:20:19 No need to apologize: as far as I remember, hardly any component has had the support you've been providing so far. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: WilB on 2019-04-03 18:47:50 @TheQwertiest Code: [Select] huge blow from Mozilla and it's shenanigans That's disappointing news & hopefully not too restrictive in the future. All your excellent hard work & effort is much appreciated on this marvellous plug-in. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2019-04-20 17:51:41 Hi everybody, So this may be the successor of the excellent JScript Panel ! Great news ! Is there an updated list of the already-compatible scripts, with the corresponding codes ? That would help a lot. I'm thinking about marc2003 scripts... Plus WilB's Biography View... etc.. Thanks. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-20 22:28:38 Is there an updated list of the already-compatible scripts, with the corresponding codes ? There is no such list (yet?). All WilB's script are SMP compatible though. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-20 22:33:47 @davideleo , @WilB , thanks for your kind words and support, really appreciated =) That's disappointing news & hopefully not too restrictive in the future. It was not anything really huge (like DMCA), but rather the state of the current and the future support of Mozilla SpiderMonkey embeddings... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-22 17:15:22 Version: 1.2.0 Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.0 Changelog: Spoiler (click to show/hide) Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v120 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: kutuzof on 2019-04-23 15:03:23 https://drive.google.com/open?id=1Me4EUu65bn9vCJ4E1ZUgubPx48DaHXqK Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-23 19:16:46 @kutuzof , can you try the latest Nightly build and see if it fixes the freeze? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: louiscoim on 2019-04-23 20:41:28 Hello TheQwertiest, and everybody else, off course.. I have very simple question: Is there a way to port WSH Coverflow to an SMP Script? I mean, I know Chronial's Coverflow or even Bubble Coverflow are more advanced components, but my PC doesn't support them as I get the pixelformat error because of my old Intel HD graphics chip.. I tried everything possible to fix this issue (from drivers to installing open EL/GL solutions).. If it isn't possible, no need to tell me why, I don't know much about scripting and I must say that: I admire a lot Your work and think it's awesome!! Anyway, Thanks in Advance. Peace Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: kutuzof on 2019-04-24 07:39:49 @kutuzof , can you try the latest Nightly build and see if it fixes the freeze? Thanks, I tried the nightly build, while it seems to work well. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-24 16:35:15 Version: 1.2.1 Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.1 Changelog Hotfix for v1.2.0 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg970630.html#msg970630)) Fixed • Fixed another fb2k freeze on exit. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-04-24 17:09:04 How safe is it to add custom methods and properties to default SMP objects? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-24 18:53:04 Never tried, but should be probably safe (if it works :D), since all SMP objects are proper JS objects. Obviously there are some limitations - e.g. you can't make a deep copy of (most) SMP objects (unless it's stated explicitly otherwise in docs). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: acmodeu on 2019-04-24 21:05:30 Tried to migrate to Spider Monkey. Added volume bar from https://github.com/timonwong/foo_uie_wsh_panel_mod/blob/master/samples/Volbar%20with%20GdiDrawText.txt Got this on gr.FillGradRect( 0, 0, pos , wh, 90, RGB(240,240,240), RGB(46,48,63)); Code: [Select] Error: Spider Monkey Panel v1.2.1 (MyScript v1.2.3 by Me)FillGradRect failed:GdiPlus error: SetBlendTriangularShape failed with error (0X2): InvalidParameterFile: <main>Line: 45, Column: 2Stack trace: on_paint@<main>:45:2 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-04-24 21:42:10 Tried to migrate to Spider Monkey. Added volume bar from https://github.com/timonwong/foo_uie_wsh_panel_mod/blob/master/samples/Volbar%20with%20GdiDrawText.txt Got this on gr.FillGradRect( 0, 0, pos , wh, 90, RGB(240,240,240), RGB(46,48,63)); I think the error is generated when the width argument is equal to 0, that is when "pos" is equal to "ww". I guess you have to manage that eventuality with something like: Code: [Select] line 51 if (pos != ww) gr.FillGradRect(pos, 0, ww - pos, wh, 90, RGB(240, 240, 240), RGB(190, 190, 190)); P.S. I just realized you got the error on the previous FillGradRect function, on line 50. Obviously the same applies to both: Code: [Select]  if (pos != 0) gr.FillGradRect(0, 0, pos, wh, 90, RGB(240, 240, 240), RGB(100, 230, 100)); if (pos != ww) gr.FillGradRect(pos, 0, ww - pos, wh, 90, RGB(240, 240, 240), RGB(190, 190, 190)); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-24 22:37:02 @acmodeu, there is no need to update this sample manually - it's available as part of SMP package (samples/basic/Volbar with GdiDrawText.js). PS: @davideleo, your reasoning is correct =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-24 22:43:23 Is there a way to port WSH Coverflow to an SMP Script? You can try using the following guide: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/JScript-to-SpiderMonkey-migration-guide Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: acmodeu on 2019-04-25 14:59:16 @davideleo, @TheQwertiest thank you guys! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-04-25 17:35:14 Big thanks TheQuertiest for your work on this component! I released a theme based on this, you can get it there if you want to try it: (https://i.ibb.co/4Tmh9TB/preview-tn.jpg) https://github.com/Ottodix/Eole-foobar-theme Most of this theme is made possible by SMP Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-04-25 17:53:56 Looks awesome! Guess it's time to make that script showcase page :D It might be a good idea to create a separate thread for your theme though, otherwise it might get lost in this thread and not get the attention it deserves... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-01 18:56:47 Conceptual question: what is the use of setting to null the variable that holds the graphics object, after using the GetGraphics() and thereon the ReleaseGraphics() methods? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-05-02 14:03:59 Conceptual question: what is the use of setting to null the variable that holds the graphics object, after using the GetGraphics() and thereon the ReleaseGraphics() methods? Making sure that the GC collect and free up the allocated memory for this graphic object, if you declared it as a global variable ? That's my guess Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-02 14:58:03 ...if you declared it as a global variable... In the sample scripts I've seen, it is always declared locally and nevertheless set to null at closure. But isn't it redundant after the ReleaseGraphics() method, given how spider monkey GC works? P.S. I noticed the StackBlur (text).js sample script does not bother to set the graphics object variable to null, after running the ReleaseGraphics() method. It's the only exception, though. What is the difference, for example, with the thumbs.js sample script? Why is setting the graphics object variable to null required in the latter and not in the first? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Joulupukki on 2019-05-02 20:52:09 @TheQwertiest: many thanks for your Spider Monkey Panel! @TheQwertiest and other other developers: Would it be possible to have a simple code for a simple volume control with 2 images: a dot and a knob with your panel? (I've both images) Thanks in advance. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Joulupukki on 2019-05-04 19:00:16 Well,, I swtched to WSH panel mod and the "DarkOne Volume Knob Panel v3.1" vworks fine now with my Foobar v1.4.3 (DUI). :) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-13 15:20:15 I'm working on a one-panel theme and so I turned some of my stand-alone scripts to objects. With stand-alone scripts, though, we are able to draw portions of graphic elements by placing the drawing coordinates virtually outside of the window, relying on the fact that only the pixels inside the window will be painted. This is especially helpful (at least it helped me) in animating a scrolling motion. Obviously this trick is not available in a one-panel script, where coordinates outside of the target area (the area I actually want to paint) are nevertheless inside the main window, and will be painted anyway. So, is there a general way to mask or clip the portion of a graphic element that falls outside of a given area? Let's say I have an object with x, y, width and height properties which define a region of the window, and than a draw() method which executes a few GdiGraphics methods. I want to make sure that when the draw() method is called, only the region defined by the object x, y, width and height properties is painted. How can I achieve that? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-13 19:19:54 For the record, I actually managed to get the above mentioned effect, but I cannot stress enough how much I dislike my solution: Code: [Select] var repainting = false;var repaint_done = false;var myObj = new PaintRegion(700, 400, 500, 300)function on_paint(gr){ myObj.paint(gr);}function PaintRegion(x, y, w, h){ this.x = x; this.y = y; this.w = w; this.h = h; this.paint = (gr) => { if (repainting) // some GdiGraphics method... repainting = !repainting ; if (!repaint_done) window.RepaintRect(this.x, this.y, this.w, this.h); repaint_done = true }} I'm not comfortable triggering a RepaintRect method with the on_paint() callback and I have to pay attention that whenever the on_paint event is called, the repainting and repaint_done global variables are set to the proper value. If this is the right direction I can work on it to make it safe, but I reckon there must be a better way. P.S. After some tests with multiple objects I settled on the following version which seems to be pretty fluent: Code: [Select] function PaintRegion(x, y, w, h){ this.x = x; this.y = y; this.w = w; this.h = h; this.repainting = false; this.repaint_done = false; this.paint = (gr) => { if (this.repainting) //draw something...; this.repainting = !this.repainting; if (!this.repaint_done) window.RepaintRect(this.x, this.y, this.w, this.h); this.repaint_done = !this.repaint_done }} Still looking forward to insights from skilled coders. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-13 23:44:11 Update: the above solution is okay if the objects are separate, but it gets buggy when they overlap. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2019-05-14 18:38:02 Unless I'm missing something, RepaintRect just clips the area that is currently drawn to the screen. So if I draw a rectangle from 0,0,100,100 to the gr buffer, and I'm only painting the region from (50,50 -> 100,100), the next time a full repaint is done, the rectangle will be completely drawn from 0,0 -> 100,100. Also, it's my understanding that RepaintRect isn't something that causes a draw to happen immediately. It just specifies the region which will be drawn to the screen and that region is the union of the outermost extants of the region on the next draw cycle. So if I do RepaintRect(10,10,20,20) and then another RepaintRect(1000,1000,20,20) before the contents are actually drawn, when the drawcycle occurs it'll actually draw (10,10) -> (1020,1020). I'm assuming the underlying gdi stuff hasn't changed for Spidermonkey. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-14 20:27:04 Unless I'm missing something, RepaintRect just clips the area that is currently drawn to the screen. So if I draw a rectangle from 0,0,100,100 to the gr buffer, and I'm only painting the region from (50,50 -> 100,100), the next time a full repaint is done, the rectangle will be completely drawn from 0,0 -> 100,100. Yes, unless you do this: Code: [Select] var myRegion = new PaintRegion(50, 50, 100, 100)function on_paint(gr){ myRegion.paint(gr);}function PaintRegion(x, y, w, h){ this.x = x; this.y = y; this.w = w; this.h = h; this.repainting = false; this.repaint_done = false; this.paint = (gr) => { if (this.repainting) { gr.FillSolidRect(0,0, window.Width, window.Height,0xFF000000); // these are just examples,any other gr.DrawEllipse(80, 30, 200, 200, 2, 0xFFFFFFFF) // GdiGraphics method goes here. this.repaint_done = true; this.repainting = false; }; if (!this.repaint_done) { this.repainting = true; window.RepaintRect(this.x, this.y, this.w, this.h); this.repaint_done = false; }; }} The full paint is done only if the repainting property is true, but this is set to false by default and it is not touched when a full paint is called. It is turned to true only for the RepaintRect method to reference it, and than back to false right after its execution. The repaint_done property works the other way round, in order to prevent a RepaintRect loop. The above code works, but in my new project I built a system of nested objects, that pass the paint action (any action actually) on to their content, and that's where it gets tricky, but it's a very specific problem for that script. Anyway, I'd prefer, and I'm still looking for (I still did not look into the Catrox scripts! :-[ ), an alternative method that doesn't use the on_paint() callback to trigger the RepaintRect() method, for obvious safety reasons, but also because it would probably work in my nested objects chain. Also, it's my understanding that RepaintRect isn't something that causes a draw to happen immediately. I'm not sure about that. From what I read in the docs, it behaves like the Repaint() method. Doesn't that call an immediate window repaint? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-14 23:10:11 Sorry, I just realized the last line of code which resets the repaint_done property to false, must not be in the conditional section, but right after: Code: [Select] var myRegion = new PaintRegion(50, 50, 100, 100)function on_paint(gr){ myRegion.paint(gr);}function PaintRegion(x, y, w, h){ this.x = x; this.y = y; this.w = w; this.h = h; this.repainting = false; this.repaint_done = false; this.paint = (gr) => { if (this.repainting) { gr.FillSolidRect(0,0, window.Width, window.Height,0xFF000000); // these are just examples,any other gr.DrawEllipse(80, 30, 200, 200, 2, 0xFFFFFFFF) // GdiGraphics method goes here. this.repaint_done = true; this.repainting = false; }; if (!this.repaint_done) { this.repainting = true; window.RepaintRect(this.x, this.y, this.w, this.h); }; this.repaint_done = false; // <--------- }} I don't really understand why, though. It seems that the RepaintRect method aborts the execution of the previously called on_paint() function that triggered it. Is that correct? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-15 00:11:46 I don't really understand why, though. It seems that the RepaintRect method aborts the execution of the previously called on_paint() function that triggered it. Is that correct? Alright, I think I understand now what @MordredKLB was telling me in his previous reply (https://hydrogenaud.io/index.php/topic,116669.msg971412.html#msg971412): the new paint event called by the RepaintRect() method is queued and executed only when the first paint event that triggered it is popped off the stack. Right? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2019-05-15 01:23:49 Alright, I think I understand now what @MordredKLB was telling me in his previous reply (https://hydrogenaud.io/index.php/topic,116669.msg971412.html#msg971412): the new paint event called by the RepaintRect() method is queued and executed only when the first paint event that triggered it is popped off the stack. Right? Not exactly. Say you have a function that calls window.RepaintRect() twice in a row so that two buttons are repainted. It's my understanding that your on_paint method will only be called once the next time a WM_PAINT message is received by the foobar window, and that the cliprect for the area drawn will be the union of the exterior bounds (although that I'm less sure on). Basically the Javascript is single-threaded, but the operating system isn't, and it queues up the areas that will be drawn. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-05-18 16:19:43 I finally found out how @TheQwertiest managed to solve the above issue in his CatRox theme. It's pretty straightforward actually, but it took me a few days because it was buried in thousands of code lines. So, for who's interested, here is a proper and more reasonable way than the one I came up with: Code: [Select] var myRegion = new PaintRegion(100, 100, 200, 200)function on_paint(gr){ myRegion.paint(gr);}function PaintRegion(x, y, w, h){ this.x = x; this.y = y; this.w = w; this.h = h; this.paint = (gr) => { var clipImg = gdi.CreateImage(this.w, this.h) var grClip = clipImg.GetGraphics(); grClip.DrawEllipse(100, 50, 200, 200, 2, 0xFF000000) clipImg.ReleaseGraphics(grClip); gr.DrawImage(clipImg, this.x, this.y, this.w, this.h, 0, 0, this.w, this.h) }} Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-06-05 11:43:45 Hello, I have a question about on_size event. It has two parameters and documentation indicates that it corresponds to panel size. I have tested that and saw that it correspond to window size. I did not do the test with JScript panel, but I would like to know if it the same with the JScript Panel ? Kind regards, Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-06-05 13:44:42 I have a question about on_size event. It has two parameters and documentation indicates that it corresponds to panel size. I have tested that and saw that it correspond to window size. That is impossible - SMP currently does not have a way to find the size of fb2k window. on_size arguments ARE panel width and height respectively. You can easily verify this by creating a layout with two resizeable SMP panels (e.g. in DUI) and replacing the following line in the default script: Code: [Select] gr.GdiDrawText(g_text, g_font, g_hot ? g_textcolour_hl : g_textcolour, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX); with Code: [Select] gr.GdiDrawText(width:${ww}, height ${wh}, g_font, g_hot ? g_textcolour_hl : g_textcolour, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX); Each panel will display it's size, which will change when they are resized. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-06-05 18:30:31 Thanks for you response. I was already displaying width and height but is was the same for my for 4 panels. After more testing, I decided to add a MinWidth and MaxWidth, idem with height. And it is not respected. I use CUI with horizontal and vertical splitter. The thing is that a panel stretch to the size of the largest panel inside a column, even if larger than MaxWidth. When you say 'resizeable SMP panel', do you mean that we can have them not resizeable? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-06-17 11:50:40 After more testing, I decided to add a MinWidth and MaxWidth, idem with height. And it is not respected. I use CUI with horizontal and vertical splitter. MinWidth and MaxWidth properties (and window dimensions adjustment functionality) are not provided by SMP component, but rather by foo_ui_hacks =) You can use the following code though from my CaTRoX theme though: https://github.com/TheQwertiest/CaTRoX_QWR/blob/61eecfa4159e3714d58f53ae942d5f1861e83fb2/theme/Scripts/Panel_Menu.js#L1018 Note, that you have to change assignments like MinWidth=True to MinWidth.Enabled=True. When you say 'resizeable SMP panel', do you mean that we can have them not resizeable I mean smth like parent vertical/horizontal splitter in DUI/CUI that allows for panel size adjustment. There are components that provide panels for CUI/DUI, which allow having other panels inside, but don't allow their resizing. [EDIT] Disregard this, I can't read... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-06-26 10:11:57 Hi, Does someone knows a trick to trigger a new evaluation of panel stack splitter scripts, from a SMP panel ? There is the play/pause way, using the function below, because the PerTrack scripts of a PSS panel are evaluate on playback changes, but this creates some sound glitches, especially while playing live streams (because foobar can't buffer the stream when this is a live stream, it need to synchronize with the stream after a pause command) Code: [Select] function RefreshPSS() { if (fb.IsPlaying || fb.IsPaused) { fb.PlayOrPause(); fb.PlayOrPause(); } else { fb.Play();fb.Stop(); }} Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2019-06-26 19:38:11 Hi, Does someone knows a trick to trigger a new evaluation of panel stack splitter scripts, from a SMP panel ? There is the play/pause way, using the function below, because the PerTrack scripts of a PSS panel are evaluate on playback changes, but this creates some sound glitches, especially while playing live streams (because foobar can't buffer the stream when this is a live stream, it need to synchronize with the stream after a pause command) Code: [Select] function RefreshPSS() { if (fb.IsPlaying || fb.IsPaused) { fb.PlayOrPause(); fb.PlayOrPause(); } else { fb.Play();fb.Stop(); }} There is a trick you can try. You will need to enable is the PSS panels "Evaluate scripts when track info is modified" Change your function to Code: [Select] function RefreshPSS() {let handle_list = plman.GetPlaylistItems(plman.ActivePlaylist);handle_list.RefreshStats();} There is a limitation: Your handle list cannot be empty. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-06-26 21:28:21 Ah yes, thanks! By combining both methods, you end up with something which work all the time: Code: [Select] function RefreshPSS() { if (fb.IsPlaying || fb.IsPaused) { let handle_list = new FbMetadbHandleList(fb.GetNowPlaying()); handle_list.RefreshStats(); } else { fb.Play();fb.Stop(); } } Important point: "Evaluate scripts when track info is modified" needs to be enabled AND on the script tab of the PSS panel, "Titleformat mode on startup" needs to be on "now playing" Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-06-27 13:44:23 @cerbaire , I have to apologize: my last answer was answering the wrong question, since I've misread MinWidth (present in SMP/JSP) as MinSize.Width (foo_ui_hacks)... But you've probably read the (correct) answer by marc2003 by now, so I won't repeat it here... :shame_on_me: Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-06-27 19:17:17 @cerbaire , I have to apologize: my last answer was answering the wrong question, since I've misread MinWidth (present in SMP/JSP) as MinSize.Width (foo_ui_hacks)... But you've probably read the (correct) answer by marc2003 by now, so I won't repeat it here... :shame_on_me: Thanks TheQwertiest, yes I saw marc2k3 response on GitHub. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: spuuunit on 2019-06-27 20:56:20 How can I use foobar2000 code with Spider Monkey Panel code? This is what I want to do: Code: [Select] $if(%ispaused%,❚❚,▶)‌‌%title%%playback_time% / %length%

This is my Spider Monkey Panel code so far:
Code: [Select]
var font = gdi.Font("Segoe UI", 12, 0);function Color(r, g, b) {	return 0xFF000000 | r << 16 | g << 8 | b;}function on_paint(gr) {    gr.FillSolidRect(0, 0, 1000, 1000, Color(240,240,240));    gr.GdiDrawText("Playing/Paused - Track Title", font, Color(0,0,0), 5, 1, 226, 1000);    gr.GdiDrawText("00:00 / 00:00", font, Color(0,0,0), 237, 1, 1000, 1000);}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-06-28 14:12:54
Hi everyone,

Does anyone ever hear of a SMP (or marc2003's jscript) code for an library search toolbar (like the Quicksearch toobar component for example?)
There used to be a WSH toolbar in one of Br3tt's theme (xchange I think) but it's kind of old and I'm not sure I will be able to port it to SMP.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-06-29 00:27:57
Hi everyone,

Does anyone ever hear of a SMP (or marc2003's jscript) code for an library search toolbar (like the Quicksearch toobar component for example?)
There used to be a WSH toolbar in one of Br3tt's theme (xchange I think) but it's kind of old and I'm not sure I will be able to port it to SMP.

Not sure it helps, but here is an adaptation of the script I wrote for my config. It was not meant to work in a component-like fashion, so you might have to edit the code here and there (no window properties, sorry). My coding is much more naive than marc2003's or Br3tt's, but perhaps this makes it easier to grasp and modify.
For reasons I don't understand, it only works with columns ui, maybe some more advanced coder can figure out why,
I still didn't find the time to handle the typing animation when the text's length exceeds that of the width of the panel, so make sure the panel is wide enough for your average search strings.
Search results are displayed in a playlist called "Search results [your search string]", which is overwritten at every new search.

Code: [Select]
"use strict";include(fb.ComponentPath + "docs\\flags.js");include(fb.ComponentPath + "docs\\helpers.js");include(fb.ComponentPath + "samples\\complete\\js\\lodash.min.js");var font_height = 18;var fontcolor = colours.White;var text = "";var cursor = 0;var set_cursor = false;var selection_lx = 0;var selection_rx = 0;var selection = "";var mouse_lbtn_down = false;var count = 0;var timerID;var timer = false;var edit = false; var writing = false;var ctrla = false;var dblclk = false;var dblclk_lx = 0;var dblclk_rx = 0;var mouse_lbtn_down_x = 0;var mouse_move_x = 0;var obj = new ActiveXObject("htmlfile");var autocomplete = new Array();var history = new Array();history.push(text);var currentState = 0;var ww = 0;var wh = 0;var text_x = 0;function on_size(){    ww = window.Width;    wh = window.Height;  }function on_paint(gr){        var iconfont = "Segoe mdl2 assets";        var font = gdi.Font(iconfont, font_height, 0);    var selection_color = colours.Black;    var icon = String.fromCharCode(57492);     var textheigth = gr.CalcTextHeight(icon, font);      text_x = wh + gr.CalcTextWidth(" ", font);        dblclk_lx = Math.max(text.slice(0, getPos(mouse_lbtn_down_x, text, font, gr)).toString().lastIndexOf(" ") + 1, 0);    dblclk_rx = getPos(mouse_lbtn_down_x, text, font, gr) + (text + " ").slice(getPos(mouse_lbtn_down_x, text, font, gr)).toString().indexOf(" ") + 1;    selection_lx = getPos(Math.min(mouse_lbtn_down_x, mouse_move_x), text, font, gr);    selection_rx = getPos(Math.max(mouse_lbtn_down_x, mouse_move_x), text, font, gr);    if (dblclk) selection_lx = Math.min(selection_lx, dblclk_lx);    if (dblclk) selection_rx = Math.max(selection_rx, dblclk_rx);    if (ctrla) selection_lx = 0;    if (ctrla) selection_rx = text.length;            var selection_x = text_x + (gr.CalcTextWidth(text.slice(0, selection_lx), font));    var selection_w = gr.CalcTextWidth(text.slice(selection_lx, selection_rx), font);    var text1 = text.slice(0, selection_lx);    var text2 = text.slice(selection_lx, selection_rx);    var text3 = text.slice(selection_rx);    if (set_cursor) {        cursor = getPos(mouse_lbtn_down_x, text, font, gr);        set_cursor = false;    }    selection = text2;    var cursor_x = text_x + gr.CalcTextWidth(text.slice(0, cursor), font);         gr.DrawRect(0, 0, ww - 1, wh - 1, 1, fontcolor);     gr.GdiDrawText(icon, font, fontcolor, 0, 0, wh, wh, DT_CENTER | DT_VCENTER | DT_SINGLELINE);      gr.FillSolidRect(selection_x, (wh - textheigth)/2, selection_w, textheigth, colours.Gray);           gr.GdiDrawText(text1, font, fontcolor, text_x, 0, gr.CalcTextWidth(text1, font), wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);    gr.GdiDrawText(text2, font, selection_color, text_x + gr.CalcTextWidth(text1, font), 0, gr.CalcTextWidth(text2, font), wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);    gr.GdiDrawText(text3, font, fontcolor, text_x + gr.CalcTextWidth(text1, font) + gr.CalcTextWidth(text2, font), 0, gr.CalcTextWidth(text3, font), wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);    if (selection_w == 0 && edit && count%2 == 1) gr.DrawLine(cursor_x, (wh - textheigth)/2, cursor_x, (wh + textheigth)/2, 1, fontcolor);    if (text == "" && !edit) gr.GdiDrawText("Search", font, fontcolor, text_x, 0, ww - text_x, wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE);    writing = false;}function on_mouse_move(x, y){    window.SetCursor(IDC_IBEAM);    if (mouse_lbtn_down){        mouse_move_x = x;        window.Repaint();	}}function on_mouse_lbtn_down(x, y){    edit = true;    mouse_lbtn_down = true;    mouse_lbtn_down_x = x;    set_cursor = true;    unselect();    window.Repaint();}function on_mouse_lbtn_up(x, y){    mouse_lbtn_down = false;}function on_mouse_lbtn_dblclk(x, y){    mouse_lbtn_down = true;    mouse_lbtn_down_x = x;    dblclk = true;        window.Repaint();}        function on_mouse_leave(){    mouse_lbtn_down = false;    edit = writing;}function on_focus(is_focused){    if (is_focused){        timerID = window.SetInterval(function() {            count++;            window.Repaint();            }, 500);            timer = true    } else {        window.ClearInterval(timerID);        timer = false;        count = 0;        window.Repaint();    }}function on_char(code){    if (code > 31) {        if (selection_lx < selection_rx){            text = text.slice(0, selection_lx) + String.fromCharCode(code) + text.slice(selection_rx);            cursor = selection_lx + 1;            unselect();        } else {                        text = text.slice(0, cursor) + String.fromCharCode(code) + text.slice(cursor);            cursor = cursor + 1;        }        newState(text);        var autocompleteMenu = window.CreatePopupMenu();        var filtered_list = _.uniq(autocomplete, true).filter(filterAutocomplete);        for (var i = 0; i < filtered_list.length; i++){            autocompleteMenu.AppendMenuItem(MF_STRING, i + 1, filtered_list[i]);        }        var ret = autocompleteMenu.TrackPopupMenu(text_x, wh, 0);        if (ret > 0){            text = filtered_list[ret - 1];            cursor = text.length;        }        writing = true;        window.Repaint();    }}        function on_key_down(vkey){    var ShiftKeyPressed = utils.IsKeyPressed(VK_SHIFT);    var ControlKeyPressed = utils.IsKeyPressed(VK_CONTROL);    if (!ControlKeyPressed){               switch (vkey){                        case 8: //backspace                        if (selection_lx < selection_rx){                text = text.slice(0, selection_lx) + text.slice(selection_rx);                cursor = selection_lx;                unselect();            } else {                text = text.slice(0, Math.max(cursor - 1, 0)) + text.slice(cursor);                cursor = Math.max(cursor - 1, 0);            }            newState(text);            break;                        case 13: //enter            search();            text = "";            cursor = 0;            history = [];            newState(text);            break;                        case 37: //left arrow            cursor = Math.max(cursor - 1, 0);            break;                        case 39: //right arrow            cursor = Math.min(cursor + 1, text.length);            break;                        case 46: //delete            if (selection_lx < selection_rx){                text = text.slice(0, selection_lx) + text.slice(selection_rx);                cursor = selection_lx;                unselect();            } else {                text = text.slice(0, cursor) + text.slice(cursor).slice(1);            }            newState(text);            break;        }    } else {        switch (vkey){            case 65: //ctrl + A            ctrla = true;            break;                        case 67: //ctrl + C            obj.parentWindow.clipboardData.setData("Text", selection);            break;                        case 86: //ctrl + V            var clipboard = obj.parentWindow.clipboardData.getData("Text") + "";            if (selection_lx < selection_rx){                text = text.slice(0, selection_lx) + clipboard + text.slice(selection_rx);            } else {                text = text.slice(0, cursor) + clipboard + text.slice(cursor);             }            cursor = selection_lx + clipboard.length;            unselect();             newState(text);                        break;                        case 88: //ctrl + X            obj.parentWindow.clipboardData.setData("Text", selection);            text = text.slice(0, selection_lx) + text.slice(selection_rx);            cursor = selection_lx;            unselect();            newState(text);            break;                        case 89: //ctrl + Y            currentState = Math.max(currentState - 1, 0);            text = history[currentState];            cursor = text.length;            break;                        case 90: //ctrl + Z            currentState = Math.min(currentState + 1, history.length - 1);            text = history[currentState];            cursor = text.length;            break;                 }    }    window.Repaint();}            function getPos(x, text, font, gr){    var pos;    for (var i = 0; i <= text.length; i++){        if (x < text_x + gr.CalcTextWidth(text.slice(0, i + 1), font)){            pos = i;            i = text.length + 1;        } else {            pos = text.length;        }    }    return pos;}	    function unselect(){    mouse_move_x = mouse_lbtn_down_x;    dblclk = false;    ctrla = false;}function newState(text){    history.slice(currentState);    history.unshift(text);    currentState = 0;}function search(){    autocomplete.push(text);    autocomplete.sort();        var SortOrder = "%album artist%|%release date%|%album%|%discnumber%|%set subtitle%|%tracknumber%|%path%";    try {        var queryItems = fb.GetQueryItems(fb.GetLibraryItems(), text);    }    catch(Error){        var queryItems = fb.CreateHandleList();    }        var index = -1;         for (var i = 0; i < plman.PlaylistCount; i++) {       if (plman.GetPlaylistName(i).indexOf("Search results [") == 0) index = i;    }    if (index > -1){        plman.RemovePlaylist(index);    } else {        index = plman.PlaylistCount;    }    plman.CreatePlaylist(index,"Search results [" + text + "]");    plman.InsertPlaylistItems(index, 0, queryItems);    plman.SortByFormat(index, SortOrder);      plman.ActivePlaylist = index;}function filterAutocomplete(value){    return value.indexOf(text) == 0;}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: CrowRabbit on 2019-06-29 14:40:24
Hi,

I wrote to able use Spider Monkey Panel in TypeScript.
https://github.com/FuCrowRabbit/SpiderMonkeyPanelForTypeScript

Thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-06-29 14:46:23
Oh god I just figured out how to write my panel! Kind of like a short status bar:

Code: [Select]
var font = gdi.Font("Segoe UI", 12, 0);var play_pause = fb.TitleFormat('if(%ispaused%,❚❚,▶)');var title = fb.TitleFormat('%title%');var time1 = fb.TitleFormat('%playback_time%');var time2 = fb.TitleFormat('%length%');function on_playback_pause() { // + play window.Repaint();}function on_playback_new_track() { window.Repaint();}function on_playback_seek() { window.Repaint();}function on_playback_time() { window.Repaint();}function Color(r, g, b) { return 0xFF000000 | r << 16 | g << 8 | b;}function on_paint(gr) { gr.FillSolidRect(0, 0, 1000, 1000, Color(240,240,240)); gr.GdiDrawText(play_pause.Eval() + " " + title.Eval(), font, Color(0,0,0), 5, 1, 226, 1000); gr.GdiDrawText(time1.Eval() + " / " + time2.Eval(), font, Color(0,0,0), 237, 1, 1000, 1000);} But does anyone know if there's a way to update just one string, and not the whole panel like window.Repaint(); does? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-06-29 15:05:48 @spuuunit , you can use RepaintRect(w,h) instead of Repaint() if you want to redraw only part of the panel. @CrowRabbit , TS typings would be nice, but I'm wary of the duplicated documentation: there is already a JSDoc version https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/component/docs/js/foo_spider_monkey_panel.js , and it would be a pain to have to maintain the same docs in TS typings as well... (I mean method descriptions and stuff, I'm fine with maintaining the interface itself) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: spuuunit on 2019-06-29 15:34:06 @spuuunit , you can use RepaintRect(w,h) instead of Repaint() if you want to redraw only part of the panel. @CrowRabbit , TS typings would be nice, but I'm wary of the duplicated documentation: there is already a JSDoc version https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/component/docs/js/foo_spider_monkey_panel.js , and it would be a pain to have to maintain the same docs in TS typings as well... (I mean method descriptions and stuff, I'm fine with maintaining the interface itself) Thanks! But how exactly does that look like, is it like this: window.RepaintRect(0, 1000, 0, 1000); Does that cover the whole area? Because nothing is updating for me. And another thing: The playback time that increases every second is what I want to update. Is it worth updating just that area all the time, rather than the whole panel, to save resources? Or does panel update affect resources so little that I shouldn't bother? EDIT: This is my panel by the way. 4 tags and a background color: https://imgur.com/Pds7rqY Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-06-29 16:17:26 That's cause you are using it wrong =) The method prototype is window.RepaintRect(x,y,w,h) and you calling it like window.RepaintRect(x,w,y,h). So, in your case, the correct call would be window.RepaintRect(0, 0, 1000, 1000). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: spuuunit on 2019-06-29 16:32:34 Oh shit thanks! =) But does RepaintRect require less computer power than only Repaint? If so I'll go with that. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-06-29 16:37:26 RepaintRect will use less CPU only if the area it's redrawing is smaller then your whole panel. Otherwise there will be no difference. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: spuuunit on 2019-06-29 16:47:28 Ok thanks! I have 2 more questions, sorry to be a nuicense. O:) 1. Is it possible to draw text right aligned? 2. Is it possible to draw an external image, a PNG for example. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Decalicatan_Decalicatan on 2019-06-29 18:43:04 Not sure it helps, but here is an adaptation of the script I wrote for my config. It was not meant to work in a component-like fashion, so you might have to edit the code here and there (no window properties, sorry). My coding is much more naive than marc2003's or Br3tt's, but perhaps this makes it easier to grasp and modify. For reasons I don't understand, it only works with columns ui, maybe some more advanced coder can figure out why, I still didn't find the time to handle the typing animation when the text's length exceeds that of the width of the panel, so make sure the panel is wide enough for your average search strings. Search results are displayed in a playlist called "Search results [your search string]", which is overwritten at every new search. Thank you! Very much appreciated :) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-06-30 11:45:56 Thank you! Very much appreciated :) Don't bother ask if you need help understanding the script or indications on which variables must be edited to change the appearance. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Decalicatan_Decalicatan on 2019-07-01 10:26:53 Don't bother ask if you need help understanding the script or indications on which variables must be edited to change the appearance. Thanks for the offer ^^ .... Maybe you can help me for a more generic question then: Where can I find character codes if I wanted to change the search icon in the line "var icon = String.fromCharCode(57492);"). (I already managed to change the font / color / other stuffs) Thanks in advance.. and thanks once again to profide me the script,, even I you prefer not to answer, which I can undersand. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-07-01 11:33:48 Maybe you can help me for a more generic question then: Where can I find character codes if I wanted to change the search icon in the line "var icon = String.fromCharCode(57492);"). (I already managed to change the font / color / other stuffs) Well, I guess it depends on the new font you chose. You can look it up in the windows character map application where it is shown as UTF-8 code, you than have to convert it to decimal in order to use it in the fromCharCode method (I use online converters for this purpose). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-01 11:37:10 1. Is it possible to draw text right aligned? See documentation for GdiDrawText method, specifically format argument. 2. Is it possible to draw an external image, a PNG for example. See docs for LoadImageAsync/LoadImageAsyncV2, DrawImage/GdiDrawBitmap methods and basic LoadImageAsync.js/LoadImageAsyncV2.js samples. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Decalicatan_Decalicatan on 2019-07-01 13:27:16 Well, I guess it depends on the new font you chose. You can look it up in the windows character map application where it is shown as UTF-8 code, you than have to convert it to decimal in order to use it in the fromCharCode method (I use online converters for this purpose). Thank you. The hex to decimal conversion part was what I missed. Now it's working. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: spuuunit on 2019-07-01 23:17:03 1. Is it possible to draw text right aligned? See documentation for GdiDrawText method, specifically format argument. 2. Is it possible to draw an external image, a PNG for example. See docs for LoadImageAsync/LoadImageAsyncV2, DrawImage/GdiDrawBitmap methods and basic LoadImageAsync.js/LoadImageAsyncV2.js samples. God thank you! I found those documentation files, didn't even know they were there. Finally I put together my panel and it's perfect. =) Thank you TheQwertiest for an awesome plugin and all the support! This plugin must give endless possibilities for you guys who really know how to script. Keep up the good work! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-02 15:01:36 I found those documentation files, didn't even know they were there. Finally I put together my panel and it's perfect. FYI, there is a JS version and HTML version of the docs. You want the HTML version, which is accessible via Context Menu>Configure Panel>Help>View Help. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-07-12 14:12:14 1. Is it possible to draw text right aligned? See documentation for GdiDrawText method, specifically format argument. 2. Is it possible to draw an external image, a PNG for example. See docs for LoadImageAsync/LoadImageAsyncV2, DrawImage/GdiDrawBitmap methods and basic LoadImageAsync.js/LoadImageAsyncV2.js samples. Is it possible to load an image directly from an url ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-12 16:00:03 Is it possible to load an image directly from an url ? Nope, you'll have to download it manually: SMP does not provide any direct means to work with the Web, you have to use a suitable COM object via ActiveObjectX interface (e.g. ActiveObjectX("MSXML2.XMLHTTP"). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-07-16 15:46:01 Is it possible to load an image directly from an url ? Nope, you'll have to download it manually: SMP does not provide any direct means to work with the Web, you have to use a suitable COM object via ActiveObjectX interface (e.g. ActiveObjectX("MSXML2.XMLHTTP"). I have created a code using XMLHttpRequest that can download binary stream of file under Chrome, but it does not work inside a SMP panel (using a the ActiveX component instead of XMLHttpRequest object), and then I don't find anyway to save the stream to filesystem. Any clue appreciated. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-07-17 18:48:47 It's not an easy problem. You can try to look at the code of the Biography script by Wilb, there (https://hydrogenaud.io/index.php/topic,112913.msg929674.html#new), it calls a VBScript in order to download images (well his VBScript can actually download any kind of file). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: whyonearth on 2019-07-22 03:20:00 • With foobar2000 v 1.5 beta 6 and foo_spider_monkey_panel nightly build v1.2.2-beta+8a02533a I observe constant memory usage growing in following scenario: • Install foobar2000 in default configuration • Edit DUI layout by replacing Playlist Tabs container with Spider Monkey Panel • Edit default script with adding Code: [Select] const obj = new ActiveXObject('Shell.Application'); in initialization section (for example, right after "use strict";) • Save script (or reload it) many times (10-20 times will do) to produce noticeable growing of memory used by foobar2000 process This specific scenario is described here just for the sake of reproducibility. But generally speaking, it looks like Spider Monkey Panel leaks memory on script reload by not "freeing" COM objects instantiated in reloaded script. This behavior makes it problematic to iteratively develop scripts with relatively memory hungry COM objects (like 1-2 MB on instantiation). • I'd like to control foobar2000 UI with keyboard and, in doing so, to focus on Spider Monkey Panel by using standard Tab/Shift-Tab keys. However, now it's not possible. Can this feature be added? I suggest to extend JavaScript API with things like Spoiler (click to show/hide) And also add checkbox in Panel Features menu (named "Can be focusable by Tab key"), off by default to be backward compatible. Checkbox state should be mirrored in related window property on script reload. These property/functions/preference are possibly not so good named. Any other names will be also fine for me. • Given that Spider Monkey Panel JavaScript API allows to instantiate a COM object, it would be nice if this instantiation ability in addition to default registry-based approach of locating required DLLs in system-wide locations would also support decoupled from registry, private, manifest-file-based side-by-side DLL assemblies. If this would be possible, third-party DLLs with useful COM objects could be distributed with custom Spider Monkey Panel scripts and being used from these scripts without requiring administrator rights for registering DLLs in system registry. Technically, it requires usage of Activation Contexts (https://docs.microsoft.com/en-us/windows/win32/sbscs/activation-contexts) and Activation Context API (https://docs.microsoft.com/en-us/windows/win32/sbscs/using-the-activation-context-api). My little brain dump concerning possible implementation:Spoiler (click to show/hide) • As a somewhat amalgamation of all items above, here is an example for enabling usage and control of AutoHotkey scripts from Spider Monkey Panel script by loading in-process COM server without requiring administrator rights for registering related DLL. AutoHotkey (https://en.wikipedia.org/wiki/AutoHotkey) allows users of most levels of computer skill to automate repetitive tasks in any Windows application. User interfaces can easily be created, extended or modified by AutoHotkey. Loading in-process AutoHotkey DLL (instead of separate program) and controlling AutoHotkey script execution from Spider Monkey Panel script solved my problem of synchronous startup and termination of both scripts. Background in (not-)short:Spoiler (click to show/hide) Note that this example uses Microsoft.Windows.ActCtx (https://docs.microsoft.com/en-us/windows/win32/sbscs/microsoft-windows-actctx-object) ActiveX object available starting from Windows Server 2003 (for desktop users it means, starting from Windows Vista). Example:Spoiler (click to show/hide) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-22 11:24:06 With foobar2000 v 1.5 beta 6 and foo_spider_monkey_panel nightly build v1.2.2-beta+8a02533a I observe constant memory usage growing in following scenario It's not really leaking: garbage collector in SMP has several triggers, two of them are allocated memory trigger and allocation count trigger. The problem is that I can't know the size of a loaded ActiveXObject, so it doesn't trigger GC as much as it should. But, if you are actively using your script (instead of just reloading it =)), it should encounter one of the GC triggers sooner or later and will free all the memory occupied by ActiveXObject's. Regarding your suggestions: noted, but I don't think I'll work on these any times soon - I have a few major features that I really want to implement and it will take quite a lot of time... COM objects being a major PITA (and the lack of documentation) also doesn't help. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-22 11:48:06 @Awesomeo : moved SMP specific discussion here, as to not clutter @WilB 's thread. And vice versa, I could have any PSS element that would react to changes in a particular SMP. So maybe something likeset_smp(smp_id,property,value) and $get_smp(smp_id,property). This is not possible - PSS does not provide any way to extend it's API. What I will (probably) do is add an additional panel option, which would allow to define panel events that could be used by fb2k shortcuts. Hm, not sure if I fully understand this, because both things happen at once for me: playback pauses and the library tree search field receives a space. Playback pause/play shortcut uses 'on_key_down' event (which is not passed to script in this case), library tree uses 'on_key_up' event (which is passed). However I've already checked other CUI panels with typing option, like 'Typefind' or 'Youtube Source Search' and keystrokes work locally in them, they don't execute foobar's global hotkeys Dunno about Youtube Source, but it seems that 'Typefind' uses quite a hacky method to workaround this problem. I'm not quite ready to make such hacks (might change my mind though). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: whyonearth on 2019-07-22 15:31:19 With foobar2000 v 1.5 beta 6 and foo_spider_monkey_panel nightly build v1.2.2-beta+8a02533a I observe constant memory usage growing in following scenario It's not really leaking: garbage collector in SMP has several triggers, two of them are allocated memory trigger and allocation count trigger. The problem is that I can't know the size of a loaded ActiveXObject, so it doesn't trigger GC as much as it should. But, if you are actively using your script (instead of just reloading it =)), it should encounter one of the GC triggers sooner or later and will free all the memory occupied by ActiveXObject's. OK, I think I understand this. SMP garbage collector had been tuned to kick-in based on reasonable criterias. And instantiation of ActiveX object doesn't produce any meaningful information that can contribute to this criteria, so garbage collector just have no reasons to react to growing memory usage. Problem is, even though multiple saving/reloading is a laughable use-case (not in bad sense), I really did it on valid purpose, when I iteratively developed SMP script. Change script a little, save, try it out. Repeat. With instantiation of AutoHotkey COM object (as I described in list item 4), memory usage grows in about 1-2 MB chunks on every save/reload event. I think, I have not so modern computer, with just 2GB RAM, and Windows 10 is memory-hungry too, so I hit OOM. I really did. Foobar2000 process just was killed. That's a bad experience. So maybe, if tuning GC kick-in criteria now requires changes to C++ code and recompilation of SMP, the solution to my problem would be a possibility for user to contribute to criteria with JavaScript API. Something like Code: [Select] window.TriggerSmpGcAsap() Calling such function will trigger SMP garbage collector as soon as possible even though criterias defined in C++ code aren't fulfilled yet. With this function I can do something like Code: [Select] const gc_memory_criteria = 20 * (1024 * 1024 * 1024); // 20 MBfunction on_script_unload() { if (window.PanelMemoryUsage > gc_memory_criteria) { window.TriggerSmpGcAsap() }} Also, even though you don't know the size of a loaded ActiveXObject, but I (as user) can observe memory usage growing and make an assumption about this size. So maybe there could be a way to pass this information from JavaScript to component, like Code: [Select] const obj = newActiveXObject('Some.MemoryHungry.COM.Object')window.AssumeObjectSizeInGcCriteria(obj, 2*1024*1024*1024 /*2 MB*/); Regarding your suggestions: noted, but I don't think I'll work on these any times soon - I have a few major features that I really want to implement and it will take quite a lot of time... COM objects being a major PITA (and the lack of documentation) also doesn't help. I totally agree about COM technology being PITA :'( and I didn't even interact with it in C++, so I can only imagine how it is (but I don't want to, sorry ;D). However, all of my suggestions for new SMP features don't directly touch COM. I implemented Tab key focusing by setting WS_TABSTOP (https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles) window style for SMP control from AutoHotkey script. So I suggested adding of JavaScript API for enabling/disabling this style from SMP panel script. And suggestion about extending JavaScript API for manipulating activation contexts also don't need COM programming at all. Just introducing thin wrapper for instantiating ACTCTX (https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-tagactctxa) structure and calling CreateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-createactctxa), ActivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-activateactctx) and DeactivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-deactivateactctx). There are also other function in Activation Context API (https://docs.microsoft.com/en-us/windows/win32/sbscs/activation-context-reference), but they are possibly not so important for simple use-cases like mine. But anyway, it's just a clarification. I understand that SMP development is driven by your motivation and motivation can be substantially lowered by unwanted distractions. I'm the only one who asked for this features, and I can live without them for long time or even forever, as I've found workarounds. So it's totally OK for me to know that these features wouldn't be implemented soon or wouldn't be implemented at all. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-22 17:08:18 Something like Code: [Select] window.TriggerSmpGcAsap() I will not implement such method if I can avoid. Reason is simple: users ALWAYS try to shoot themselves in the foot, e.g. call ForceGC in every on_paint event and then complain that the performance is bad. I'll try to think of a better way to solve your problem (hoping there is one). window.AssumeObjectSizeInGcCriteria(obj, 2*1024*1024*1024 /*2 MB*/); Same with exposing such internals. API should be kept as concise as possible (I would remove/reorganize quite a few methods from the current SMP if I could do so without breaking compatibility). PS: 2*1024*1024*1024 is 2GB =) And suggestion about extending JavaScript API for manipulating activation contexts also don't need COM programming at all. Just introducing thin wrapper for instantiating ACTCTX (https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-tagactctxa) structure and calling CreateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-createactctxa), ActivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-activateactctx) and DeactivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-deactivateactctx). These are not general-purpose methods so they would never be placed in the core namespaces, maybe they could be added as static methods of ActiveXObject... (or perhaps a candidate for a SMP plugin, once/if such plugin API is implemented). About tabbing: I'll take a look, but no ETA =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: whyonearth on 2019-07-22 18:33:33 PS: 2*1024*1024*1024 is 2GB =) Yep, you are right, the code was wrong, the code comment is correct. Don't know how it happened. Thanks for noticing. It's good to know that you've took a closer look at suggested features. I'll patiently wait. If you don't want to give user any access to GC control knobs, it might be enough to force GC in C++ code just after invoking JS on_script_unload() callback (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/3467e78e0266a7e03c8c08a0cf1fc1acdd6305d6/foo_spider_monkey_panel/js_panel_window.cpp#L944) (maybe force conditionally, based on state of checkbox added in Panel Features menu). As far as I can deduce from looking at code, it should cover cases of saving script in panel configuration window and script reload. After all, on reload most (all?) references in unloaded script should be unreachable and targeted for garbage collection anyway. As I'm using AutoHotkey, I'm looking for ways to push information from AutoHotkey script to SMP script (pulling information from AutoHotkey script and pushing information to AutoHotkey script could be done with COM object methods). AutoHotkey can send (or post) windows messages (https://hotkeyit.github.io/v2/docs/commands/PostMessage.htm) to windows and controls with given parameters. As my limited understanding of SMP component code allows me to suppose, SMP's on_main_menu() callback is invoked based on specific window message number and argument passed to on_main_menu() callback is parameter of window message. So it could be used for my purposes. However, window message number (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/5589fb60982f066b24f44f0315b0ce8fefd1444d/foo_spider_monkey_panel/user_message.h#L64) for invoking on_main_menu() callback can change between releases of SMP, because of possible changing of related enums where this number is defined. This makes relying on concrete number a bit reckless. Can you provide separate callback (like on_wm_user_message()), which would be called on receving windows message with stable number? Or maybe you can expose main_menu_item message number in property accessible from JS script (like window.MAIN_MENU_ITEM_WM_NUMBER), so that I can push it to AutoHotkey script? (Concrete names of functions and properties are not important.) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-07-24 15:47:11 HI, Is there a way to get a playlist track metadb without retrieving the whole content of the target playlist? I'm trying to get the focused track of a playlist (any playlist, not the active one). So i've got that Code: [Select] var focus_index = plman.GetPlaylistFocusItemIndex(playlistIndex); var metadbs = plman.GetPlaylistItems(playlistIndex);metadb = metadbs[focus_index]; But in term of performance, it means that i will temporary create a object containing the whole playlist, isn't it an issue on very large playlist? I would prefer something like Code: [Select] plman.GetPlaylistItemByIndex(playlistIndex, item_index); Or eventually, something like that, in order to get the FbMetadbHandle instead of just the index Code: [Select] plman.GetPlaylistFocusItem(playlistIndex); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-24 16:45:45 I have created a code using XMLHttpRequest that can download binary stream of file under Chrome, but it does not work inside a SMP panel (using a the ActiveX component instead of XMLHttpRequest object), and then I don't find anyway to save the stream to filesystem. Sorry, forgot to answer your post: xhr in chrome/mozilla/edge is not the same as *legacy* xhr which is XMLHttpRequest activexobject. It's possible to manually invoke it in JavaScript in SMP, but the problem is that it's impossible to save the file asynchronously, meaning that it will block the main thread until the operation is finished. The solution to this is to invoke the download&save operation in a separate process. One such example is the one @Ottodix mentioned: invoke the download with a separate VBScript via cscript,exe: VBScript file - samples\complete\vbs\download.vbs; example usage - samples\complete\js\thumbs.js (https://github.com/marc2k3/smp_2003/blob/98fb2425975dcd8d3e999a7f25282392403d60dd/js/thumbs.js#L525) it might be enough to force GC in C++ code just after invoking JS on_script_unload() callback Actually I was thinking about it when I was tuning GC, but decided against it exactly due to the scenario when user reloads script a lot to test his changes. I should try to trigger a minimal GC though, since minimal GC has minimal impact on UX. Can you provide separate callback (like on_wm_user_message()) I can't, since it will tank the performance - crossing JS <> native boundary is not free and message loop is one of the most often called places. Or eventually, something like that, in order to get the FbMetadbHandle instead of just the index Uhm, you could just call fb.GetFocusItem() though? =) But yea, there is currently no way to get a single track (except for the focused track) from the playlist without fetching the array containing the whole playlist. [EDIT]: I can't currently think of a proper scenario when you would have a track index, but wouldn't have the whole playlist or means to access the corresponding track: you are either working with the whole playlist or you need a specific track because of it's status (that is selected, focused, queued and etc) which means that you can access them via corresponding methods. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-07-25 10:29:40 Uhm, you could just call fb.GetFocusItem() though? =) fb.GetFocusItem() works only on the active playlist. This is inside a on_item_focus_change(playlistIndex, from, to) callback. In this callback, I would like to get the focused track handle, and this status is effectively focused, but ! Not in the active playlist unfortunately Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-25 10:44:58 Hm... Just wondering, why would you need a focused track from non-active playlist? =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-07-25 16:23:53 Hm... Just wondering, why would you need a focused track from non-active playlist? =) this is a little bit complex, i'm building a side panel which show infos about the focused track, it needs to interact with others panels showing tracks from a playlist which is not necessary the active one (and i can't make it the active one without triggering on_playlist_switch everywhere, and it would be a major performance drawback on my layout). I think i will try to trigger a refresh of this "info panel" without on_item_focus_change but instead with on_notify_data() and a custom on_focus_change function, all my panels are SMP panels anyway, it will allow me a better control EDIT: Yes, it's much easier to control with with on_notify_data(), less foobar-logic-compliant, but it doesn't matter Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: thisbanisnotsettoexpire on 2019-07-26 02:15:20 Something like Code: [Select] window.TriggerSmpGcAsap() I'll try to think of a better way to solve your problem (hoping there is one). I (whyonearth) was banned for not really considering forum rules. I hope now I'm complying with them. Sorry for breaking the rules and for confusion with replying from new account. Anyway, that OOM-on-repeated-script-reload error I was talking about was not an OOM error at all. Nevertheless, it's still error of resource exhaustion type. So, I noted that there was some free memory at the time of crash. This is when I thought I might be wrong in my conclusions. Then I somehow did look more thoroughly at foobar2000 crash report and accidentally 93MB of .rar files extracted meaningful information (crash report is trimmed here): Spoiler (click to show/hide) So, code tried to access address zero, when last win32 error was error with code 1114 (ERROR_DLL_INIT_FAILED (https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299-): A dynamic link library (DLL) initialization routine failed). I examined AutoHotkey_H sources, then downloaded OllyDbg and tried to trace AutoHotkey DLL execution. Starting point was in DllGetClassObject (https://github.com/HotKeyIt/ahkdll/blob/eec985c16ff284ec77bde2423bb584c3a7fb1463/source/dllmain.cpp#L1199). Here's what I found. Spoiler (click to show/hide) Relevant links:Spoiler (click to show/hide) So, when I naively chose Win32w_MT variant of AutoHotkey.dll from release distribution, I chose statically linked library (which I didn't know at the time) and this brought some fixed limits. Good news, in recent version of Windows 10 this limit is raised: read here (https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/3546c3c4-1b36-4552-85c5-1b3ba860ee84/how-many-dlls-can-be-loaded-in-a-process-using-loadlibrary-?forum=windowssdk#2e017194-025e-4521-bee0-aad21fd1f805) and here (https://www.gearslutz.com/board/showpost.php?p=13729254&postcount=62&s=b7f43881db1fa1a81da3cc76ceba2e51). Bad news (for me), I'm not using the recent version of Windows 10. So, while I can instead use dynamically linked AutoHotkey.dll (from Win32w directory), which is linked with vcruntime140.dll, just as foobar2000, and this replacement seems to fix crashes, I thought, maybe if SMP component would just unload COM DLL on unloading (i.e. reloading) SMP script, this also should fix my problem? While, looking at the SMP code, I can find CoFreeUnusedLibraries (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/9252b68ba8caca8cecc0a9a9f64b76c8bacd314a/foo_spider_monkey_panel/js_objects/active_x_object.cpp#L420), I believe, in real usage component doesn't always work as expected. Trying to prove that normally used CoFreeUnusedLibraries certainly should free FLS indexes allocated by COM DLL (at least, by AutoHotkey.dll), I did some experiments: Spoiler (click to show/hide) So, I think this is where SMP can be improved. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-26 15:15:44 @thisbanisnotsettoexpire : that's quite a research you did there =) I'm not sure if this is SMP bug, since it seems that AHK reserves new FLS on every execution, but as I said I will add some GC on panel unload. Not sure when will it happen though, since MS released a broken Visual Studio update, which made it impossible to compile SMP (and I just can't find enough motivation to go through the whole VS reinstallation process to get the working VS back). <rant>This f***ing s***-show makes me wonder if they even go through QA before making a release...</rant> <rant intensifies>And don't even get me started on this f***ing disgusting compact title-bar...</rant> Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2019-07-26 20:44:01 @thisbanisnotsettoexpire : that's quite a research you did there =) I'm not sure if this is SMP bug, since it seems that AHK reserves new FLS on every execution, but as I said I will add some GC on panel unload. Not sure when will it happen though, since MS released a broken Visual Studio update, which made it impossible to compile SMP (and I just can't find enough motivation to go through the whole VS reinstallation process to get the working VS back). <rant>This f***ing s***-show makes me wonder if they even go through QA before making a release...</rant> <rant intensifies>And don't even get me started on this f***ing disgusting compact title-bar...</rant> Is this VS2019 - 16.2.0 you're talking about? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: thisbanisnotsettoexpire on 2019-07-27 04:07:27 As far as I can understand from sources, SMP allows to pass JS function as argument to COM object method. Passed function is wrapped in IDispatch-able gateway and this function could be invoked from COM object side by using gateway's ExecuteValue() (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L79) method. AutoHotkey_H COM object can assign value to variable in AutoHotkey script with ahkassign (https://hotkeyit.github.io/v2/docs/commands/ahkassign.htm) method. Though documentation says that only string value can be passed to that method and assigned to variable, in fact, as AutoHotkey_H sources show, CoCOMServer::ahkassign (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/dllmain.cpp#L803) recognizes different COM types (calling AssignVariant (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L757), then VariantToToken (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L620)). By passing VT_DISPATCH COM value to ahkassign, it's possible to assign AutoHotkey object to AutoHotkey script variable and then invoke IDispatch methods from AutoHotkey side by using same-named object methods. I successfully tested this functionality of AutoHotkey_H COM object with Python script: Spoiler (click to show/hide) But when I used AutoHotkey_H COM object in SMP JS script in the same way as in Python script, trying to call JS function from AutoHotkey script side, it produced access violation error on ExecuteValue() call from AutoHotkey script. JS script code:Spoiler (click to show/hide) In tests I used following versions: Spoiler (click to show/hide) I tried to trace SMP code with OllyDbg, found that ExecuteValue() is really called on SMP component side and (if my understanding is right) in this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L97) Code: [Select] JS::RootedObject jsGlobal( pJsCtx_, heapMgr.Get( globalId_ ).toObjectOrNull() ); heapMgr.Get( globalId_ ) returned 0. If I'm right, can it be fixed? (Just asking about possibility, not pushing to do it ASAP.) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: thisbanisnotsettoexpire on 2019-07-28 15:29:04 While, looking at the SMP code, I can find CoFreeUnusedLibraries (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/9252b68ba8caca8cecc0a9a9f64b76c8bacd314a/foo_spider_monkey_panel/js_objects/active_x_object.cpp#L420), I believe, in real usage component doesn't always work as expected. Trying to prove that normally used CoFreeUnusedLibraries certainly should free FLS indexes allocated by COM DLL (at least, by AutoHotkey.dll), I did some experiments: So, I think this is where SMP can be improved. In that experiments I used CoUninitialize and it was critical for successful results, but, while it's OK to use this function in the end of execution of standalone script, now I believe (basing on CoUninitialize documentation (https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-couninitialize)), that using it in SMP is either not allowed at all, or at least would require cooperation between author of foobar2000, authors of all other components and author of SMP (i.e. it's impractical). Turns out, just using CoFreeUnusedLibraries wasn't enough to produce noticable releasing of FLS indexes, because Quote CoFreeUnusedLibraries does not immediately release DLLs that have no active object. There is a 10-minute delay for multithreaded apartments (MTAs) and neutral apartments (NAs). For single-threaded apartments (STAs), there is no delay. No, it's not a quote from CoFreeUnusedLibraries documentation (https://docs.microsoft.com/ru-ru/windows/win32/api/combaseapi/nf-combaseapi-cofreeunusedlibraries), it's a quote from CoFreeUnusedLibrariesEx documentation (https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cofreeunusedlibrariesex). Thanks a lot, Microsoft. CoFreeUnusedLibrariesEx is specifically provided to set explicit delay for unloading DLLs with a way to force the unloading of DLLs without any delay, though remarks in CoFreeUnusedLibrariesEx documentation warn against forcing immediate unloading of DLLs. With using CoFreeUnusedLibrariesEx I can consistently release FLS indexes in test script without CoUninitialize: Spoiler (click to show/hide) The problem is, with any reasonable delay (even reasonably small delay), there probably would still be no useful change in my original SMP's usage scenario (in the concrete case of using statically linked AutoHotkey DLL), because in reloading script new AutoHotkey COM object would be created by reloaded script in a time smaller than that delay and then AutoHotkey DLL wouldn't be unloaded and allocated FLS indexes wouldn't be released and foobar2000 will still crash after repeated script reloading. But anyway, it looks like this particular mysterious mystery of strange mystery is resolved and, with this information, maybe TheQwertiest will come up with some heuristic to use the possibility of setting COM DLLs unload delay. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-07-29 13:17:50 Is this VS2019 - 16.2.0 you're talking about? Yup I tried to trace SMP code with OllyDbg, found that ExecuteValue() is really called on SMP component side and (if my understanding is right) in this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L97) Code: [Select] JS::RootedObject jsGlobal( pJsCtx_, heapMgr.Get( globalId_ ).toObjectOrNull() ); heapMgr.Get( globalId_ ) returned 0. If I'm right, can it be fixed? (Just asking about possibility, not pushing to do it ASAP.) This should not ever happen - it's a bug. Can you try the nightly build (see OP for the link) and check if the bug persists? PS: Thanks for the detailed repro steps! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: thisbanisnotsettoexpire on 2019-08-08 14:58:49 I tried to trace SMP code with OllyDbg, found that ExecuteValue() is really called on SMP component side and (if my understanding is right) in this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L97) Code: [Select] JS::RootedObject jsGlobal( pJsCtx_, heapMgr.Get( globalId_ ).toObjectOrNull() ); heapMgr.Get( globalId_ ) returned 0. I changed debugger from OllyDbg to x64dbg (https://x64dbg.com/) (it has 32-bit version and can debug 32-bit code, despite the name) and, coincidentally, place of error also changed. I didn't try to debug with OllyDbg again, so I can't say whether I was just plainly wrong in quoted bug report, or there was some misunderstanding on my side. However, after several attempts at debugging with x64dbg, I successfully found bugfix. I patched foo_spider_monkey_panel v1.2.1 (https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.1) DLL at following offsets (from the beginning of file):  Offset Original value Patched value 0x3F779 0xFF 0x90 0x3F77A 0xD7 0x90 Originally I used runtime patching ability of x64dbg and exported patch in .1337 format. It looks like offsets in this patch are not from the beginning of the file, so it wasn't useful for me per se, but for completeness I paste it here:Spoiler (click to show/hide) Original values are assembled as CALL EDI instruction and patch replaces it with NOPs. In terms of C++ sources, patch removes this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/667bfffec3df96a8e8b36b70240739d728eddeac/foo_spider_monkey_panel/js_objects/active_x_object.cpp#L812) in ActiveXObject::Invoke method: Code: [Select] VariantClear( &args[i] ); After patching, I can execute JS script from quoted post without any errors, but with producing expected result of appending an entry to foobar2000 console. As ExecuteValue method is the default member of SMP's COM object (i.e. it is identified by DISPID_VALUE (https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/cb9d0131-c6bd-463d-9c40-7264856a10c5)), it can also be invoked from AutoHotkey side by using following syntax: Spoiler (click to show/hide) If I'm right, can it be fixed? (Just asking about possibility, not pushing to do it ASAP.) This should not ever happen - it's a bug. Can you try the nightly build (see OP for the link) and check if the bug persists? After replacing foo_spider_monkey_panel v1.2.1 to v1.2.2-beta+8a02533a I observe Access Violation error on the ahk.ahkExec('f.ExecuteValue()'); line. Though I can't say that it's the same bug. In absence of .pdb for nightly and having working stable DLL, I didn't try to debug nightly to find the cause of error. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-08 15:56:04 @thisbanisnotsettoexpire : that's some extensive debugging! It's really weird though that VariantClear causes errors: it just cleans up arguments that were generated for function call (and it should be safe for well-formed COM types). Not doing this will cause memory leaks. Nevertheless, I can't test nor debug this (nor continue the component development) since I still don't have a working Visual Studio installation: current version (16.2) is broken and I couldn't find a way to download the previous release... PS: Corresponding .pdb symbols (as well as a debug build) are available on the appveyor agent - https://ci.appveyor.com/project/TheQwertiest/foo-spider-monkey-panel/builds/26070987/job/nxn00otulu6tyrl7/artifacts Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: thisbanisnotsettoexpire on 2019-08-09 14:06:02 It's really weird though that VariantClear causes errors: it just cleans up arguments that were generated for function call (and it should be safe for well-formed COM types). Not doing this will cause memory leaks. Thanks for hint. I guess then it's working, but wrong solution. VariantClear (https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-variantclear): Quote clears a VARIANTARG by setting the vt field to VT_EMPTY. The current contents of the VARIANTARG are released first. [...] If the vtfield is VT_DISPATCH, the object is released. So I've took an attempt to come up with solution from other side and patched AutoHotkey_H DLL v2.0-a100-H104: Spoiler (click to show/hide) It changes 0x6A 0x00 to 0x6A 0x01, i.e. PUSH 0 to PUSH 1. In terms of original source, it modifies function CoCOMServer::ahkassign (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/dllmain.cpp#L803) by changing argument false in function call (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/dllmain.cpp#L812) to true: Code: [Select] AssignVariant(*var, value, false); It means that AssignVariant (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L757) is called with argument aRetainVar = true, then VariantToToken (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L620) is called with argument aRetainVar = true, then reference count for an interface pointer to a COM object is incremented (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L718). I'm not sure that it's correct bugfix (is AutoHotkey_H really must be responsible for incrementing reference counter?), but it also works with Spider Monkey Panel v1.2.2-beta+8a02533a. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-09 16:22:13 After some incredible shenanigans I've managed to get myself a working VS2019 16.1 installation (no thanks to Microsoft)! Anyways... @thisbanisnotsettoexpire : I've managed to reproduce your crash - it seems that the COM object passed to ahkassign does not have it's counter incremented. Code: [Select] ...function f();...ahk.assign('f', f);... SMP wraps function f in a COM object and passes it to ahk.assign. So, we have the following scenario: - COM object is created from JS object. It has a usage counter equal to 1. - COM object is passed to ahk.assign. Usage counter was not incremented in ahk.assign. - Local (to SMP) COM object is destroyed. Usage counter is decremented to zero thus the VARIANT is destroyed as well. - If ahk tries to use said (destroyed) COM object it will invoke UB and most likely crash. Quote is AutoHotkey_H really must be responsible for incrementing reference counter? Yes, because the caller does not how the passed object will be utilized. COM object handling is the same as shared_ptr. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-09 17:06:29 @thisbanisnotsettoexpire : I've tested with the debug build of AHK and my guess was proven true - AHK assign does not increase ref count. This is the code which assigns my COM object to internal ASH variable: https://github.com/HotKeyIt/ahkdll/blob/7e6d355db20d6faf59d8a15fcc908b52ff7b5d80/source/script_com.cpp#L731 There is no reference increments going on unless aRetainVar was set to true (which is not the case for ahkassign). [EDIT] Moreover, it seems that ahkassign will actually DECREASE refcount of the incoming object WITHOUT incrementing it in some cases (invoking UB if the caller didn't increase refcount) : e.g. https://github.com/HotKeyIt/ahkdll/blob/7e6d355db20d6faf59d8a15fcc908b52ff7b5d80/source/script_com.cpp#L698 This code is flawed and I can't find any sensible scenario when it would be a correct approach. Your AHK patch *is* the correct fix. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-12 12:02:11 Well f**k... VS 2019 was updated to 16.2 on the build agent, so now SMP can't be built there... And there is still no answer from Microsoft on this issue... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-08-19 16:24:01 It's not an easy problem. You can try to look at the code of the Biography script by Wilb, there (https://hydrogenaud.io/index.php/topic,112913.msg929674.html#new), it calls a VBScript in order to download images (well his VBScript can actually download any kind of file). Thank you Ottidix and TheQwertiest. It works great. It was finally quite simple but I did no get the idea by myself ! Another question ; I have an error 'can't access dead object' ! Any suggestion on why this error is raised ? I will check the livecycle of my object, but if you have any clue (I reset SMP parameters in 'Advanced / Tools / SMP settings, but not sufficient) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-08-19 16:43:30 Another question ; I have an error 'can't access dead object' ! Any suggestion on why this error is raised ? It completely depend of your code, there is a lot of possible scenarios. One common mistake : if you send a object from another panel using window.NotifyOthers(name,info), you need to clone the object inside the corresponding callback on_notify_data(name,info) of the receiver panel, you can't just assign by reference to another variable. Because the "info" object is destructed at the end of this function. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-20 12:09:20 @cerbaire , Ottodix's suggestion is entirely correct. You can find more info about it in the documentation of on_notify_data callback (you can access HTML documentation via 'Configure...'>'Help'>'View Help'). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-08-20 17:05:13 @cerbaire , Ottodix's suggestion is entirely correct. You can find more info about it in the documentation of on_notify_data callback (you can access HTML documentation via 'Configure...'>'Help'>'View Help'). Thanks for your responses. I understand the problem, and I think I am not in the scenario of a on_notify_data call. My object is a FbMetadbHandle stored in a list. I will check on which event I am binded, but I think I instantiate my object directly in the panel script so it is not binded to any documented SMP event. I check that tonight and let you know. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Ottodix on 2019-08-21 09:58:05 Then it's really impossible to help without the code, you can debug it yourself though. You can use a function like: Code: [Select] function debug_dead_item(metadb_list,index){ console.log("desired index: "+index+", list length: "+metadb_list.length); console.log(metadb_list[index].RawPath); } Put checkpoints in your code with this function in order to trace when/where this object was available and when/where it's not anymore, and then you'll probably understand what's going on. This function will crash if the list or if the specified index doesn't exist, but it doesn't matter, the crash message will be as good an information than the console messages. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-21 10:28:32 Thanks for your responses. I understand the problem, and I think I am not in the scenario of a on_notify_data call. My object is a FbMetadbHandle stored in a list. I will check on which event I am binded, but I think I instantiate my object directly in the panel script so it is not binded to any documented SMP event. I check that tonight and let you know. The problem might be delayed: e.g. Code: [Select] // Pseudo codelet arr = []on_notify_data(data) { // no error arr.push_back(data);}on_mouse_click() { // error console.log(arr[0].Path);} On another note: what SMP version are you using? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-08-21 12:18:14 Thanks for your responses. I understand the problem, and I think I am not in the scenario of a on_notify_data call. My object is a FbMetadbHandle stored in a list. I will check on which event I am binded, but I think I instantiate my object directly in the panel script so it is not binded to any documented SMP event. I check that tonight and let you know. The problem might be delayed: e.g. Code: [Select] // Pseudo codelet arr = []on_notify_data(data) { // no error arr.push_back(data);}on_mouse_click() { // error console.log(arr[0].Path);} On another note: what SMP version are you using? I am using last nightly build available. In the panel code, I call GetPlaylistItems(-1) in a setTimeout() and store index and FbMetadbHandle returned by GetPlaylistItems. Later, in a on_mouse_lbtn_up, I use the previous stored FbMetadbHandle, and it fail. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-21 14:22:02 I am using last nightly build available. In the panel code, I call GetPlaylistItems(-1) in a setTimeout() and store index and FbMetadbHandle returned by GetPlaylistItems. Later, in a on_mouse_lbtn_up, I use the previous stored FbMetadbHandle, and it fail. That's really weird. Can you provide a minimal repro scenario? So that I could reproduce it locally. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-08-22 00:14:50 I am using last nightly build available. In the panel code, I call GetPlaylistItems(-1) in a setTimeout() and store index and FbMetadbHandle returned by GetPlaylistItems. Later, in a on_mouse_lbtn_up, I use the previous stored FbMetadbHandle, and it fail. That's really weird. Can you provide a minimal repro scenario? So that I could reproduce it locally. You're right ! I was storing FbMetadbHandle in a function called from on_notify_data, and using that handle after the callback end. I replace the handle by the RawPath property and it works better! Thank you for putting me in the right direction. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-22 11:16:49 You're right ! I was storing FbMetadbHandle in a function called from on_notify_data, and using that handle after the callback end. I replace the handle by the RawPath property and it works better! Thank you for putting me in the right direction. No! You are using it wrong! Please, read documentation for the on_notify_data... Your usage (for both FbMetadbHandle and FbMetadbHandle.RawPath) is covered explicitly in the method description. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2019-08-22 13:51:56 You're right ! I was storing FbMetadbHandle in a function called from on_notify_data, and using that handle after the callback end. I replace the handle by the RawPath property and it works better! Thank you for putting me in the right direction. No! You are using it wrong! Please, read documentation for the on_notify_data... Your usage (for both FbMetadbHandle and FbMetadbHandle.RawPath) is covered explicitly in the method description. Right! I now use JSON.parse(JSON.stringify(metadb)) to store a copy of my handle and it works lke a charm. Thanks. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-08-22 15:17:06 Right! I now use JSON.parse(JSON.stringify(metadb)) to store a copy of my handle and it works lke a charm. Thanks. Uhm... no... Code: [Select] ... If you want to store the data from info you have to perform a deep copy:- String(info) for strings.... So if you want to store metadb.RawPath, you store it like this: Code: [Select] // Pseudo codeg_storage = []on_notify_data(metadb){ // String performs a deep copy g_storage.push_back(String(metadb.RawPath))} You can't serialize metadb since it's not a serializable object (i.e. it will be restored into a simple struct instead after deserialization). To clone metadb you'll have to clone metadbhandlelist instead (metadb does not have a copy constructor): Code: [Select] // Pseudo codeg_storage = []on_notify_data(metadb){ // FbMetadbHandleList constructor always performs a deep copy let tmpHandleList = new FbMetadbHandleList(metadb); g_storage.push_back(tmpHandleList[0]);} Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2019-08-29 07:24:11 Is there a way to get an arbitrary URL to open in a browser from FSM (or jscript)? I was thinking this was simple, then when I tried to implement it, I realized that all the times I'd seen it done required foo_run, along with pre-defined URLs. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: thisbanisnotsettoexpire on 2019-08-29 10:11:42 Is there a way to get an arbitrary URL to open in a browser from FSM (or jscript)? I was thinking this was simple, then when I tried to implement it, I realized that all the times I'd seen it done required foo_run, along with pre-defined URLs. Maybe Shell.ShellExecute (https://docs.microsoft.com/en-us/windows/win32/shell/shell-shellexecute) will work? Code: [Select] const objShell = new ActiveXObject("Shell.Application");objShell.ShellExecute("https://hydrogenaud.io"); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2019-08-29 12:53:42 Is there a way to get an arbitrary URL to open in a browser from FSM (or jscript)? I was thinking this was simple, then when I tried to implement it, I realized that all the times I'd seen it done required foo_run, along with pre-defined URLs. Use Wshshell.Run with WScript.Shell Sample function https://github.com/marc2k3/smp_2003/blob/ed613ee3875cc914ea102a763758457431cdfc25/js/helpers.js#L516 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-08-29 15:42:35 Back from my holidays, the lastfm album art downloader is not working anymore. It is an old script by marc2003 that I modified now and then. It is quite obvious that the reason is a change in the lastfm web page HTML code. It is likely a silly problem, but I'm not familiar with HTML, so maybe someone here can help me out. The following is - as far as I understand - the relevant code which needs some change: Code: [Select] include(fb.ComponentPath + 'samples\\complete\\js\\lodash.min.js');include(fb.ComponentPath + 'samples\\complete\\js\\helpers.js')include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');var x = new ActiveXObject("Microsoft.XMLHTTP");var ar = panel.tf("$meta_sep(artist,', ',' and ')");var al = panel.tf("%album%");x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true);x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");x.send();var o = _.first(_.filter(_getElementsByTagName(x.responseText, "img"), {"className" : "image-list-image"}));

The issue is in the last line of the above code. It used to fetch the first of the album covers on the album lastfm page, such as this one (https://www.last.fm/music/Alessandro+Alessandroni/Prisma+Sonoro/+images). I've been looking at this part of the HTML code (from line 1077 in the aforementioned example page):
Code: [Select]
    <ul class="image-list">                    <li class="image-list-item-wrapper">                <a href="/music/Alessandro+Alessandroni/Prisma+Sonoro/+images/829db16b90ed471cbbfe248ef08ada39" class="image-list-item">                    <img                        src="https://lastfm-img2.akamaized.net/i/u/avatar170s/829db16b90ed471cbbfe248ef08ada39.webp"                        alt="None"                    >                </a>            </li>                    <li class="image-list-item-wrapper">                <a href="/music/Alessandro+Alessandroni/Prisma+Sonoro/+images/72cd2e7b55604336b9003de58bf58d24" class="image-list-item">                    <img                        src="https://lastfm-img2.akamaized.net/i/u/avatar170s/72cd2e7b55604336b9003de58bf58d24.webp"                        alt="None"                    >                </a>            </li>                    <li class="image-list-item-wrapper">                <a href="/music/Alessandro+Alessandroni/Prisma+Sonoro/+images/d002704049d844f4ba5dcc647614a483" class="image-list-item">                    <img                        src="https://lastfm-img2.akamaized.net/i/u/avatar170s/d002704049d844f4ba5dcc647614a483.webp"                        alt="None"                    >                </a>            </li>            </ul>

I guess the parameters in the _getElementsByTagName function do not match the page HTML code anymore, but I cannot reference it properly.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-08-29 17:31:23
Maybe Shell.ShellExecute (https://docs.microsoft.com/en-us/windows/win32/shell/shell-shellexecute) will work?
Code: [Select]
const objShell = new ActiveXObject("Shell.Application");objShell.ShellExecute("https://hydrogenaud.io");

Use Wshshell.Run with WScript.Shell

Sample function
https://github.com/marc2k3/smp_2003/blob/ed613ee3875cc914ea102a763758457431cdfc25/js/helpers.js#L516
Thanks, guys. thisban's code worked great, but I already had Marc's helper script in my theme so I saved a line of code :)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-08-29 17:37:42
Back from my holidays, the lastfm album art downloader is not working anymore. It is an old script by marc2003 that I modified now and then. It is quite obvious that the reason is a change in the lastfm web page HTML code. It is likely a silly problem, but I'm not familiar with HTML, so maybe someone here can help me out.

The following is - as far as I understand - the relevant code which needs some change:
...

I guess the parameters in the _getElementsByTagName function do not match the page HTML code anymore, but I cannot reference it properly.
A few things:
1) The img's don't have "image-list-image" class attached to them anymore, so all images are being filtered out. You'd have to completely remove the _.filter section, or first get all "a" tags and filter by class="image-list-item" and then get all images from inside those. I haven't used those methods enough to know how to write that relevant code though.
2) Those are .webp images. Can SMP even handle those, presuming they can be scraped correctly?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-08-29 19:18:44
A few things:
1) The img's don't have "image-list-image" class attached to them anymore, so all images are being filtered out. You'd have to completely remove the _.filter section, or first get all "a" tags and filter by class="image-list-item" and then get all images from inside those. I haven't used those methods enough to know how to write that relevant code though.
2) Those are .webp images. Can SMP even handle those, presuming they can be scraped correctly?

Thanks, I'll try your suggested fixes. I don't know about the webp format yet. I wanted to fix the file download anyway, as a mean to better understand how to use the xmlhttp object. I found instructions on how to manually download the webp file as a jpg, so maybe it's possible to edit the code in order to emulate such method. Perhaps a better alternative would be to get the jpg url from the meta tag (line 65 of the HTML code in the above example page). This might be my next question.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-30 10:25:02
@davideleo , I think it should be fixed with the latest marc2003 scripts (https://github.com/marc2k3/smp_2003). Download them and put them in samples/complete.

@MordredKLB , SMP doesn't support .webp images.
[EDIT] MSDN indicates that there's some built-in support for .webp images, but there is no information on when and where such support is available (https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-constant-image-file-format-constants)

PS: I might have found a workaround that might allow me to work around MSVS issues.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-08-31 18:01:22
@davideleo , I think it should be fixed with the latest marc2003 scripts (https://github.com/marc2k3/smp_2003). Download them and put them in samples/complete.

Thanks for the link, but I cannot find the "Last.fm Album Art Downloader" script. As far as I know marc2003 stopped updating it since a few years, at least publicly.

However I tried fetching the jpg URL in the page metadata with this code:
Code: [Select]
let doc = new ActiveXObject('htmlfile');doc.open();doc.write(x.responseText);                        var o = doc.querySelector("meta[property='og:image']").getAttribute("content");doc.close();

The code correctly assigns the url, such as this one (https://lastfm-img2.akamaized.net/i/u/ar0/829db16b90ed471cbbfe248ef08ada39.jpg), to the variable "o", but the "download" visual basic script doesn't seem to like it as an argument. The code that runs the visual basic script is the following:
Code: [Select]
_runCmd("cscript //nologo " + _q(fb.ComponentPath + "samples\\complete\\vbs\\download.vbs") + " " + _q(o) + " " + _q(f), false);
where the variable "f" is the destination filename.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-09-03 17:11:18
The code correctly assigns the url, such as this one (https://lastfm-img2.akamaized.net/i/u/ar0/829db16b90ed471cbbfe248ef08ada39.jpg), to the variable "o", but the "download" visual basic script doesn't seem to like it as an argument.

Problem solved. The issue was a leftover line of the previous code (commented out in the script below) which I naively thought to be harmless.

Code: [Select]
                        let doc = new ActiveXObject('htmlfile');                        doc.open();                        doc.write(x.responseText);                                                var o = doc.querySelector("meta[property='og:image']").getAttribute("content");                        doc.close();                      //						var u = o.src.replace("avatar170s", "ar0");		  	 		   _runCmd("cscript //nologo " + _q(fb.ComponentPath + "samples\\complete\\vbs\\download.vbs") + " " + _q(o) + " " + _q(f), false);
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-09-06 18:53:33
Hello,

When I use image in my panels, for example with gdi.Image('path.to.img'), I can't delete the file from filesystem without closing foobar2000. Is there a best practice to release image handle?
Kind regards,
Nicolas
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-09-14 09:45:27
Hi, I just noticed that when I print out the track title for example ( fb.TitleFormat('%title%'); ) the character & does not display correctly. This is what it looks like (https://imgur.com/WZFkRYk). It's not a huge deal, but it would be nice if I could fix it. And ideas?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-14 13:44:39
Hi, I just noticed that when I print out the track title for example ( fb.TitleFormat('%title%'); ) the character & does not display correctly. This is what it looks like (https://imgur.com/WZFkRYk). It's not a huge deal, but it would be nice if I could fix it. And ideas?
What method are you calling to print the text? Which font are you using?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-09-15 17:26:00
I'm a little confused about the encodeURIComponent() function.
The lastfm album art downloader script uses the function to get the right URL of the lastfm album page, like this:
Code: [Select]
include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');var x = new ActiveXObject("Microsoft.XMLHTTP");var ar = panel.tf("$meta_sep(album artist,', ',' and ')");var al = panel.tf("%album%");x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al), true); This usually worked fine, but with the Damned's "The MCA Singles A's + B's" I got https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%2B%20B's (https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%2B%20B's) whereas the URL of the lastfm album page is https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's (https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's) The encodeURIComponent() function properly converts the "+" character to "%2B", but the lastfm URL shows a sort of double encoding converting the "%" character to "%25" in turn, and thus the "+" character becomes "%252B". Therefore I changed the code applying the function twce, like this: Code: [Select] "https://www.last.fm/music/" + encodeURIComponent(encodeURIComponent(ar)) + "/" + encodeURIComponent(encodeURIComponent(al)) getting a weird https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's (https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's) which surprisingly (at least for me) works as well. Can anybody explain me the logic of this double encoding? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-09-16 14:43:18 Can anybody explain me the logic of this double encoding? It seem that's just a bug in lastfm url generation. encodeURIComponent seems to perform exactly as it's described in JavaScript docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2019-09-16 14:48:13 Version: 1.2.2-preview Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.2-preview Changelog: Spoiler (click to show/hide) Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v122 PS: the version is called "preview", because it was built manually on my PC (instead of appveyor CI as before). Because of Microsoft shenanigans this is the only way right now. It will be republished as a proper non-preview version once MS fixes the bug (mind you, it's already been two months since the bug was reported). It will be the same though functionality-wise (unless there are bugs discovered, of course) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2019-09-16 15:32:52 It seem that's just a bug in lastfm url generation. encodeURIComponent seems to perform exactly as it's described in JavaScript docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent Yes, sorry my question was not clear enough. How come the double encoding works? Unlike my code, lastfm's bug generates a double encoding of only one percentage character in the URL. In other words, why does https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's (https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's) lead me to https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's (https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's)? It is as if all "%25" were interpreted as "%", but one. Mind that triple encoding doesn't work. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: spuuunit on 2019-09-16 20:55:00 What method are you calling to print the text? Which font are you using? gr.GdiDrawText. Segoe UI, and that font has the '&' character. Here's my code for clarity: Code: [Select] var font = gdi.Font("Segoe UI", 12, 0);var play_pause = fb.TitleFormat('$if(%ispaused%,❚❚,▶)');var title = fb.TitleFormat('%title%');var time1 = fb.TitleFormat('%playback_time%');var time2 = fb.TitleFormat(' / %length%');function on_playback_pause() {    window.Repaint();}function on_playback_new_track() {    window.Repaint();}function on_playback_seek() {	window.Repaint();}function on_library_items_changed() {	window.Repaint();}function on_playback_time() {	window.RepaintRect(213, 3, 85, 12);}function Color(r, g, b) {	return 0xFF000000 | r << 16 | g << 8 | b;}function on_paint(gr) {    var time_width = gr.CalcTextWidth(time1.Eval() + time2.Eval(), font);    gr.FillSolidRect(0, 0, 1000, 1000, Color(240,240,240));    gr.GdiDrawText(play_pause.Eval() + " " + title.Eval(), font, Color(0,0,0), 5, 1, 287 - time_width, 1000);    gr.GdiDrawText(time1.Eval() + time2.Eval(), font, Color(0,0,0), 297 - time_width, 1, 1000, 1000);}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-16 21:45:13
@spuuunit : GdiDrawText (which uses ::DrawText internally) uses & for some formatting rules (e.g. adding underscore to the following character). In your case you can just add DT_NOPREFIX flag (0x00000800) to the method. For more info about flags of GdiDrawText see corresponding section in docs/flags.js.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-09-17 17:39:55
@spuuunit : GdiDrawText (which uses ::DrawText internally) uses & for some formatting rules (e.g. adding underscore to the following character). In your case you can just add DT_NOPREFIX flag (0x00000800) to the method. For more info about flags of GdiDrawText see corresponding section in docs/flags.js.

Oooh, I see. That makes sense. And thanks, I added that now. :)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Madthunder on 2019-09-18 19:31:05
I had a problem moving from 1.2.1 to 1.2.2 when using the updated jsplaylist-mod.

I seems like g_font_wd2 and g_font_wd3 were undefined in WSHplaylistmanager.js and WSHtopbar.js and so I had to add the following in both files (specifically, in the functions oPlaylistManager and oTopBar):

Code: [Select]
var g_font_wd2 = {	name: "Wingdings 2",	Size: 24};		var g_font_wd3 = {	name: "Wingdings 3"};

This fixes the problem for me.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-20 21:54:38
@Madthunder , nice catch! Will be fixed in the next release.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-30 16:09:52
@AndreaT , most likely you are using up all the memory =)

Quote
At least I can have it running for a while
Do you mean that the script doesn't fail immediately?

I will try to whip up a debug build that has a more detailed error message.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-02 16:27:44
@AndreaT , most likely you are using up all the memory =)

Quote
At least I can have it running for a while
Do you mean that the script doesn't fail immediately?

I will try to whip up a debug build that has a more detailed error message.

@TheQwertiest : Yes, exactly so, the script runs for a while, even for minutes, then it crashes randomly (but quite often when making a search or browsing/scrolling through the search's results).
Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-02 17:30:47
@AndreaT, does it fail always in the same place (i.e. OrderByRelativePath)? If not, does it produce the same error message ("allocation overflow") ?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Lasternom on 2019-10-04 16:40:59
Hi all,

I've got an questions. I'm trying to make a theme selector that would changes the whole colour scheme of foobar.
I was wondering if it's possible to change the default colours in Columns UI, as shown in the attached picture, this ofcourse with the SpiderMonkeyPanel.

My apologies If I'm asking this question in the wrong place.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-05 15:29:13
I've got an questions. I'm trying to make a theme selector that would changes the whole colour scheme of foobar.
I was wondering if it's possible to change the default colours in Columns UI, as shown in the attached picture, this ofcourse with the SpiderMonkeyPanel.

My apologies If I'm asking this question in the wrong place.
AFAIK, CUI/DUI does not provide such API, so SMP can't do much about it :\
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-07 17:47:56
@AndreaT, does it fail always in the same place (i.e. OrderByRelativePath)? If not, does it produce the same error message ("allocation overflow") ?

@TheQwertiest : I am sorry, I cannot be of help about, I didn't take care of that.
As soon as a new version with improved debugging will be available, I will reinstall the component and I will take care to update you more precisely.
Many thanks.
Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-10 00:19:53
PS: Nightly builds are up again! (thanks to Appveyor team!) (no thanks to Microsoft...)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-10 17:08:02
@TheQwertiest

SMP crash on Windows 10 Pro 32bit. But working perfectly on Windows 7 Ultimate 32bit

Hello, I don't know if this is a SMP problem or a problem of Biography 1.1.1, but this happens with FB 1.5 beta 17 and 18 on Windows 10 Pro 32bit ITA version.

To be noted that I am running exactly the same configuration also on Windows 7 Ultimate 32bit ITA without any significant problems.

Thanks and regards,
Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-11 10:36:29
@TheQwertiest

SMP crash on Windows 10 Pro 32bit. But working perfectly on Windows 7 Ultimate 32bit

Hello, I don't know if this is a SMP problem or a problem of Biography 1.1.1, but this happens with FB 1.5 beta 17 and 18 on Windows 10 Pro 32bit ITA version.

To be noted that I am running exactly the same configuration also on Windows 7 Ultimate 32bit ITA without any significant problems.

Well, you are out of memory =)
This error usually happens when there are too many images loaded (or the images are too big).
The difference between Win7 and Win10 might be caused by the difference in RAM/VRAM consumption by OS (i.e. Win10 consumes more memory than Win7).
PS: How much RAM and VRAM do you have?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-11 13:01:42
@TheQwertiest

I was not out of memory, I had over 1GB available.
I have 4GB total (the max for a 32bit OS).

And also I do not agree on Windows 10 consuming more memory of Win7, it is the contrary.

Foobar (exactly the same configuration) uses 1100MB on Win7 and only 950MB on Win10.

And, question, why you point to the memory while the error is speaking about an "image/window resize error"?

Regarding the image size and the like, Biography 1.1.1 is fetching images from internet. Usually are small, a matter of kB.

Regards,
Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-11 15:59:38
why you point to the memory while the error is speaking about an "image/window resize error"?
Because Resize does not modify the current image, but creates a new resized image from the old one.

It might be something else though: it seems that GdiPlus might return OutOfMemory error even if the error has nothing to do with memory...
Another thing you could check is the amount of GDI handles used: open Task Manager (CTRL-SHIFT-ESC) > Details > Right-Mouse-Button on column header > Select columns > Check GDI objects. This will display the current number of GDI objects used by process.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-13 08:20:20
@TheQwertiest

Hi, I checked the system and everything was within the normal limits.
So, I decided to remove the Biography script, delete all the sub-folders related to Biography, but not its install where the config files are.
Then I run Foobar again and reloaded the Biography script.
Doing so, it is finally working fine.
Probably there was something corrupted in the subfolders structure or in the ACL.
I think the real error was related to some disk write error / access denied in writing.
Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-19 08:13:18
@TheQwertiest
Hello TheQwertiest, I am just reminding you that I am still having this blocking error with Library Tree:

Error: Spider Monkey Panel v1.2.2-preview+0db3c6a4 (Library Tree v2.1.2 by WilB)
OrderByRelativePath failed:
allocation size overflow

File: <main>
Line: 542, Column: 61

Stack trace:
Panel/this.sort@<main>:542:61
rootNames@<main>:1205:48
Library/this.getLibrary@<main>:1190:119
Timers/this.lib/<@<main>:2911:115

I contacted WilB once more and he gave me this reply:

As far as I am aware this seems to be a bug in spider monkey panel and outside of my control, but I am open to suggestions. I just tried again with a 642K test library & all was OK here. That particular error seems to be occurring on panel initialisation and is explicitly related to view by folder structure. So you could try a different view (if the error is locking you out you could open panel properties and find SYSTEM.View By [it's probably the last entry] and change it to 1 to set a different view).

I thought you were debugging the issue with @TheQwertiest? It sounds as though the issue is reproducible and so it ought to be possible to resolve the cause.

HTH
Last Edit: 2019-10-17 19:08:22 by WilB

Can you help me solving this issue?
Many thanks and kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-24 21:02:27
@AndreaT , regretfully, I couldn't make the debug SMP build work (yet).
... The lack of free time doesn't help either ...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-25 07:48:19
@TheQwertiest, no problem and thanks for having let me know.
If/when you will make it, kindly let me know and I will test it.
Many thanks and kind regards, Andrea.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-31 15:52:39
@AndreaT , here is the debug build for diagnosing OrderByRelativePath issue:
https://ci.appveyor.com/api/buildjobs/4fnfte0b2r6h8906/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel.fb2k-component
https://ci.appveyor.com/api/buildjobs/4fnfte0b2r6h8906/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel_pdb.zip

To turn on diagnostics you need:
1. Install *.fb2k-component as usual.
2. Unpack *_pdb.zip into the SMP component folder (e.g. user-components/foo_spider_monkey_panel).
3. Launch fb2k.
4. Preferences > Advanced > Tools > Spider Monkey Panel > C++ exception stack trace > Enable (tick).
5. Load WilB's Library Tree and reproduce the error.
6. Check fb2k console output for the stack trace.
7. Post console output here.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-31 15:59:05
@TheQwertiest : Many thanks! I will update you as soon as possible. Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-31 16:29:53
@TheQwertiest :
Hello TheQwerties, herein attached the log collected.
It should contains 3 or 4 "runs" in attempt to have the script running, but it always failed just at the initialization.
Looking forward
Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-31 17:49:43
Welp, I was right - you were out of memory =)
Good news though, I have an idea how to reduce memory usage here, which might fix your issue.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-31 17:55:03
Hi @TheQwertiest : I do not have the knowledge to question you, but I have to kindly notify you that I am having 1.5GB of physical free memory plus other 2 or 3GB of virtual memory available...
I do not understand how I can be out-of-memory...
Thanks and warm regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: kode54 on 2019-11-01 00:26:06
Virtual memory does not let you allocate more memory to a single process than can fit in its own memory space. For 32 bit applications, this is 2GB of user address space*. Even then, allocating more memory than is available can only force so much to page out to disk, and if those background processes are actively running, they cannot really be paged out so easily, without incurring a heavy load as they continue to access their own memory.

* Even with Large Address Aware, the limit is only 3GB.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: lvqcl on 2019-11-01 12:02:02
There's also such thing as memory fragmentation: https://stackoverflow.com/questions/3770457/what-is-memory-fragmentation
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: tuxman on 2019-11-01 12:11:59
Memory limits are exactly why I hesitate to try this. JavaScript virtual machines - like SpiderMonkey - have been proven to be not really low on resource usage. You pay a high price for having a non-native user interface.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-01 15:04:47
@tuxman , well each programming language has it's niche. I mean, SMP itself was written in C++, because performance and memory consumption matters for it's intended usage. But making a program in a compiled language requires much more effort than making it in a scripting language (especially for a casual user).

Regarding SMP: creating a panel component for fb2k in C++ requires quite a bit of code and a machine with configured IDE, but when using SMP (or JSP/WSH) you get that panel handling code for free and you don't need any IDE nor even a Notepad. SMP/JSP/WSH can be considered a higher level API wrapper around fb2k API, i.e. it might be not as flexible and performant, but it's much easier to use and requires much less insight in fb2k and/or Windows internals.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: tuxman on 2019-11-01 15:11:56
I don't think that a casual user should be able to write code. It is a profession for a good reason.
If resource usage would not matter, I'd dive deeper into Dopamine and similar players.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-01 15:28:25
@AndreaT , I've made a test SMP version, which has a revamped OrderByRelativePath implementation called OrderByRelativePathV2. To test it, you need to replace OrderByRelativePath with OrderByRelativePathV2 in WilB LibraryTree script.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-01 15:36:44
@tuxman , I don't agree with you, but I don't think we can have a productive discussion on this topic, so I'll just drop it.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-01 17:59:15
@AndreaT , I've made a test SMP version, which has a revamped OrderByRelativePath implementation called OrderByRelativePathV2. To test it, you need to replace OrderByRelativePath with OrderByRelativePathV2 in WilB LibraryTree script.

@TheQwertiest : Many Thanks! I am going to do that. I will update you asap. Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: kode54 on 2019-11-02 02:18:06
I don't think that a casual user should be able to write code. It is a profession for a good reason.
If resource usage would not matter, I'd dive deeper into Dopamine and similar players.
Thanks for being the gatekeeper to all things known as creative expression. Casual users should also stay away from composing music and crafting artwork as well. If it isn't a paying job, it isn't worth doing, right?

Oh, how could I be so stupid! Some kind soul has alerted me to my mistake. I have forgotten to include the fine profession of word craft. Lest we forget that you have not been paid for writing the above quoted post, so I should assume that it is not of your best quality. Do be sure to share something more akin to the writings of a professional author next time!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-02 11:14:46
@TheQwertiest :
Hello TheQwerties,

I installed your new SMP ver 1.2.3-beta (kindly note that I did NOT removed the debug library from the user-component directory and did not disabled the Advanced settings I set for the debug of the ver 1.2.3-test). I was supposed to keep all this as-is not having had different instruction.

Then I edited the Library Tree ver 2.1.2 JS as instructed (replacing all the occurances). Attached is the modified JS in case you would check if I did all right.

And this is the outcome:
1) What's good is that not Library Tree can start-up with the default view, there are no crash.
2) What's bad is that as soon as I select the View by Folder Structure, Foobar UI freezes and it doesn't came back to live even waiting 1+ hour. So, I have to kill the process Foobar.
To be noted that after the kill, I can restart Foobar and the Library Tree JS results not loaded in the target SMP panel (that panel configuration is lost or deleted by the system).

I tried this 5 times and all runs went exactly the same.
Unfortunately I could not collect any console log because of Foobar freeze.

Kindly let me know if you need me to execute some other tests or collect debug info.
Thanks and regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-02 16:00:36
@AndreaT, could you create a memory dump during freeze? Instructions: https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/61#issuecomment-470036761
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-02 16:09:47
@TheQwertiest : I will try right away. I will let you know asap.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Black_Over_Bills_Mothers on 2019-11-06 10:08:04
@Qwertyiest
Tidying my script to process new tracks. In this script I get a list of handles to be processed and then I used to call
to delete all embedded images. I've replaced this with the RemoveAttachedImages method of the handles list and it works great.

I also want to optimise my files so I currently use a context menu command;
fb.RunContextCommandWithMetadb("Utilities/Optimize file layout + minimize file size",myHandles,8);
However this generates a popup information box that I have to close every time. Would it be possible to create another method such as myHandles.OptimizeAndMinimize on the list of handles to avoid the popup message?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Black_Over_Bills_Mothers on 2019-11-09 08:56:34
Looks like our friend marc2k3 has implemented IMetadbHandleList OptimiseFileLayout in his foo_jscript_panel to address my request. Thanks marc2k3. Hopefully this will find it's way into the next foo_spider_monkey_panel.....please.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-09 18:01:02
@Black_Over_Bills_Mothers, sorry, I have quite a few things that I want (and need) to do in SMP, so it will have to wait for a bit. It is noted though, and I'll come back to it after I finish at least some of planned features.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-11 10:57:17
@AndreaT , latest nightly has OrderByRelativePath with integrated fix.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-11 12:05:59
Hello @TheQwertiest, many thanks for promptly notifing me.
I immediately tested the new Spider Monkey Panel v1.2.3-beta+61085bf2.
It is working well and in my case it saves approximately 75MB or RAM (compared with the special build you gave me dated 6 of November).
Great job!
Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-11 12:26:50
Quote
saves approximately 75MB or RAM (compared with the special build you gave me dated 6 of November)
It's probably caused by the new SpiderMonkey (JavaScript engine), which was updated in the nightly builds =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-11 13:41:04
Quote
saves approximately 75MB or RAM (compared with the special build you gave me dated 6 of November)
It's probably caused by the new SpiderMonkey (JavaScript engine), which was updated in the nightly builds =)

@TheQwertiest : But I was not using V2 method. So, I think the 75MB savings is due to the new V2 method merged into the legacy V1.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-14 20:01:42
* double post removed *
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-14 20:02:50
First time I ever see this kind of error:
Quote
Error: Spider Monkey Panel v1.2.2-preview+0db3c6a4 (test by davideleo)
Font failed:
WinAPI error: CreateFont failed with error (0x0): The operation completed successfully.

The code which generates the error is as simple as this:
Code: [Select]
this.font = gdi.Font("Segoe UI", 12);

The crash occurs only once every two times.

Any clue?

P.S.
As a test, I replaced the error generating line with the following:
Code: [Select]
this.font =  window.GetFontCUI(0);

The script still crashes once every two times, but for a different reason:
Quote
Error: Spider Monkey Panel v1.2.2-preview+0db3c6a4 (test by davideleo)
FillSolidRect failed:
GdiPlus error: FillRectangle failed with error (0x2): InvalidParameter

Once again, the error-generatng line is as innocent as it can get:
Code: [Select]
gr.FillSolidRect(this.x, this.y, this.width, this.height, colours.LightGray);
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-15 10:42:48
@davideleo , can you try the latest nightly version and check if it has the same error?

As for gr.FillSolidRect(this.x, this.y, this.width, this.height, colours.LightGray); error, this usually happens when you supply invalid dimensions. E.g. zero height or width.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-15 14:21:15
Hi @TheQwertiest , I tested the script with the nightly build and it behaves in the exact same way, notifying the same errors.
Switching from one version to the other, I watched the behavior on startup, though, which I did not consider previously. The original script (the one with gdi.Font()) always crashes on startup and at the first attempt to reload it. Subsequent attempts alternate success and failure.
The "control" script (the one with window.GetFontCUI()) totally freezes foobar2000 on startup. I can hear the sound of the crash notification, but all I see is a blank window preview when I move the mouse over the taskbar icon (see the attached picture). I can start foobar2000 (albeit with a crash) only with the original script and replace it with the control script only once foobar2000 is running. The control script will than work and crash every other time.

Something I did not mention before is that it is not a proper crash: the code stops working, but the last painted window is not replaced by the "Aw, crashed :(" orange window (I have to manually resize the window to trigger that).

As for gr.FillSolidRect(this.x, this.y, this.width, this.height, colours.LightGray); error, this usually happens when you supply invalid dimensions. E.g. zero height or width.
For doubt's sake I outputted the FillSolidRect() arguments to the console and they are the same the one time it crashes and the one it works.

P.S.
Maybe it's a clue, maybe not: I tried reverting to SMP v1.2.1 and found out that with this older version both scripts freeze foobar2000 on startup.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-16 12:28:26
Hello @TheQwertiest, I do not know why but yesterday I had again Out-of-memory errors (3 or 4 in a couple of hours) running Library Tree and the beta of SMP 1.2.3 dated (build 11 of November).
I do not remember to have done something different or unusual than the previous days...
The only big change in between is Windows 10 update from 1903 to 1909.
Kindly let me know if you need me collecting specific data/logs.
Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-16 20:21:07
Unresponsive script - Don't ask me again - Option NOT working

Hello @TheQwertiest, I noticed that even if I select the option "Don't ask me again", it doesn't work and every time I restart Foorbar I get the notifying window herein attached.

Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-17 14:34:11
Unresponsive script - Don't ask me again - Option NOT working
It's not supposed to persist between fb2k restarts, i.e. it's intentional. It only suppresses the warning in the current panel for the current fb2k instance.

Regarding OOM errors: not sure what I can do to help you. As I've said before, your library *is* huge and WilB's script is not designed for minimal memory usage (the performance of the script would have been likely worse if it was though - time-memory trade-off and all that). Maybe playing around with GC settings might help you (i.e. in preferences > advanced), but I have no specific suggestions :\

@davideleo , can you provide the script that reproduces the problem?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-11-18 07:21:29
All the best, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-19 19:18:42
@davideleo , can you provide the script that reproduces the problem?

I tried reverting to the error-generating version of the script, but I made too many edits since my last post. However, I was able to move on when I found out that the error was generated by too many repeated gdi.Font methods (the crash would occur after around 2000 iterations),

The following is a very simplified script with the same logic, which reproduces the same error:
Code: [Select]
include(fb.ComponentPath + "samples\\complete\\js\\lodash.min.js");var artists = list("artist");var grid = new Grid(artists, 12);function Cell(fontSize){	this.font = gdi.Font("Segoe UI", fontSize);}function Grid(list, fontSize){	this.cells = list.map(() => {		return new Cell(fontSize);	})	}function list(tag, handle_list = fb.GetLibraryItems()){	var tags = [];	var items = fb.GetQueryItems(handle_list, tag + " PRESENT");	for (var i = 0; i < items.Count; i++) {		var handle = items[i];		var values = fb.TitleFormat("$meta_num(" + tag + ")").EvalWithMetadb(handle); for (var j = 0; j < values; j++) { tags.push(fb.TitleFormat("$meta(" + tag + "," + j + ")").EvalWithMetadb(handle));		}	}    return _.uniq(tags.sort(), true);}

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-20 10:01:28
@davideleo , it seems that you've exhausted GDI handles. System can provide only so much GDI handles (the limit depends on the OS version and it's configuration). Since all GdiFont objects are being stored in the Grid/Cell, they can't be GC'd, thus GDI handles can't be freed. The resulting error report is weird though and I'll try to look into it.

That aside, you should reuse GdiFont objects whenever possible (instead of recreating them every time) for memory and performance sakes (and to avoid hitting GDI handle limit).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-25 20:31:07
I need the width of the playing playlist name on start up. According to the console log, I only have one on_paint event to exploit after the playing playlist is resumed, but I'd rather not overload the on_paint() callback if not strictly needed. So, is there another way to trigger the code when the playback state has been resumed, or alternatively a good reason not to?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-26 10:01:26
I need the width of the playing playlist name on start up. According to the console log, I only have one on_paint event to exploit after the playing playlist is resumed, but I'd rather not overload the on_paint() callback if not strictly needed. So, is there another way to trigger the code when the playback state has been resumed, or alternatively a good reason not to?
Not sure I understand your scenario. For playback state tracking you can use on_playback* callbacks (e.g. on_playback_pause). If you want to reduce workload in on_paint, you can always cache results (i.e. calculate width only if the playlist name changed).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-26 13:37:43
Not sure I understand your scenario.

The problem is only at startup. I use foobar2000 with the option to resume playback state checked and I never stop the player, I just  pause it. Therefore, foobar2000 starts with a playing playlist on. I have a drawtext function that takes the playing playlist name and the width of the playlist name, but the playing playlist name is not available until the very end of the startup process, when the only event left to use is the on_paint. So, is this the only option? I have no need to recalculate the width of the text at every on_paint, on_size would make more sense, but the last of the three on_size events at startup is before playlist initialization.
There is actually other stuff going on between the last on_size and the on_paint at startup, such as foo_enhanced_playcount being loaded, which makes me guess that I'd have the same issue if I were to retrieve scrobbling information at startup.
I kind of miss an on_startup_done() callback.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-26 19:57:04
Is there a way to temporary disable keyboard shortcuts?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-29 11:08:26
The problem is only at startup. I use foobar2000 with the option to resume playback state checked and I never stop the player, I just  pause it. Therefore, foobar2000 starts with a playing playlist on. I have a drawtext function that takes the playing playlist name and the width of the playlist name, but the playing playlist name is not available until the very end of the startup process, when the only event left to use is the on_paint. So, is this the only option? I have no need to recalculate the width of the text at every on_paint, on_size would make more sense, but the last of the three on_size events at startup is before playlist initialization.
There is actually other stuff going on between the last on_size and the on_paint at startup, such as foo_enhanced_playcount being loaded, which makes me guess that I'd have the same issue if I were to retrieve scrobbling information at startup.
I kind of miss an on_startup_done() callback.

Regretfully, fb2k does not provide on_startup_done callback and I can't implement it myself.

I have no need to recalculate the width of the text at every on_paint
As I've said, you can *cache* the value. Or just use a simple boolean guard
Code: [Select]
var isInitialized = false;function on_paint(){  if (!isInitialized )  {    CalculateSmth();    isInitialized =true;  }}

Quote
Is there a way to temporary disable keyboard shortcuts?
fb2k API does not provide such functionality.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-29 12:56:07
Regretfully, fb2k does not provide on_startup_done callback and I can't implement it myself.

I have no need to recalculate the width of the text at every on_paint
As I've said, you can *cache* the value. Or just use a simple boolean guard
Code: [Select]
var isInitialized = false;function on_paint(){  if (!isInitialized )  {    CalculateSmth();    isInitialized =true;  }}

I see. Thanks, I actually needed to be reassured that a workaround is needed here. I guess I'll just save the playing playlist name to a file, Talking of workarounds, I found out that you can trigger a few playlist events before the initial on_paint by adding and removing items to a playlist on start up. It's probably the closest you can get to an on_start_up_done.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-29 13:11:28
@davideleo , I've got some info from Peter (https://hydrogenaud.io/index.php?topic=117208.msg977811#msg977811), which clarified some things:
- It *might* be possible to create on_start_up_done callback. No promises or ETA though.
- on_paint and on_size callbacks *might* (and often will) be called before the fb2k is fully initialized.
:
- It *is* possible to suppress shortcuts. But no promises or ETA on that either.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-29 13:16:45
8)  You are my favorite foobar2000 component developer ♥
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-11-29 13:30:38
Haha, thanks =)
Though I don't think I deserve this title. There are far more qualified developers (e.g. musicmusic, CUI dev).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-11-29 13:51:49
- on_paint and on_size callbacks *might* (and often will) be called before the fb2k is fully initialized.

What I refer to as "start up" is probably autoplaylist initialization really. The console log shows the start up time right after all autoplaylists are set, therefore I gathered that was the last stand of the start up process. This is my usual start up log:

Quote from:  console.log
on_size
Spider Monkey panel initialized
on_size (3 times)
UI initialized
foo_custom_database initialized
autoplaylist initialized
start up done (at least start up time is written here in the console log) <-----------------
possible playlist events
on_paint

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-01 13:56:03
Hello @TheQwertiest, hoping to find you well, I am getting to you just to have an idea of when you would release the new SMP with the v1 and v2 methods merged together.
I am waiting for it in order to use Library Tree (I have then to remove because of the too frequent out-of-memory crashes).
Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-01 14:55:08
@AndreaT, it's still quite far from release, but you can use Nightly version in the meantime (Nightly/beta doesn't mean "not stable" ), it has v2 sorting method integrated.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-01 17:57:11
@AndreaT, it's still quite far from release, but you can use Nightly version in the meantime (Nightly/beta doesn't mean "not stable" ), it has v2 sorting method integrated.

Hello @TheQwertiest, ... thanks ... but your last Nightly build I downloaded few hours ago cannot be installed.
I am getting an installation error. I tried 3 times.
If you need the error code, let me know and I will try to reinstall again.
Thanks and regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-02 10:19:52
I am getting an installation error. I tried 3 times.
If you need the error code, let me know and I will try to reinstall again.
That's really weird. Is there a error message or smth like that?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-02 13:16:09
Hello @TheQwertiest, this is the error I get during the installation process:

using the link you provided for the nightly build:

Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-02 15:03:22
@AndreaT, Hmm... can you try installing debug version and see if it works?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-02 16:36:08
I need some clarification about memory usage. I'm monitoring the panel and the total memory usage of a one SMP only configuration and I was expecting the two values to coincide. Instead, panel memory usage reaches 52 MB before GC kicks in, while total memory usage is more or less stuck on 2 MB. How is that? Why is total memory usage lower than panel memory usage?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-02 17:51:11
Hello @TheQwertiest , I am getting the same error: Could not load component "foo_spider_monkey_panel.fb2k-component": bad allocation.

By the way, is it correct that this package is 57MB in size and that I had to rename the file removing the ending "_debug"?

Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-02 18:15:50
I need some clarification about memory usage. I'm monitoring the panel and the total memory usage of a one SMP only configuration and I was expecting the two values to coincide. Instead, panel memory usage reaches 52 MB before GC kicks in, while total memory usage is more or less stuck on 2 MB. How is that? Why is total memory usage lower than panel memory usage?
What smp version are you using?

Hello @TheQwertiest , I am getting the same error: Could not load component "foo_spider_monkey_panel.fb2k-component": bad allocation.
Hm... That's really weird. Can you check if installation of the latest release version (v1.2.2) works? I'm not even sure if it's a SMP error anymore...
Oh and what's your fb2k version?

By the way, is it correct that this package is 57MB in size and that I had to rename the file removing the ending "_debug"?
Yes, that's correct. Another user has informed me that I forgot to include some files though, so it wouldn't have worked even if your installation succeeded.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-02 18:25:32
What smp version are you using?

v1.2.2-preview+0db3c6a4
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-02 18:31:14
v1.2.2-preview+0db3c6a4
Calculating total memory usage is actually not a free operation in terms of performance (compared to panel memory usage), so to minimize performance impact it uses cached value, which is updated every GC cycle. In some cases (e.g. yours) this might result in incorrect values. I'll see if smth can be done to make reported values more accurate.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-02 18:35:50
Thanks for the answer. Since it's a one-panel configuration, can I presume the total memory consumption to be that of the only panel, or does the component use more memory besides the panel shares?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-02 18:41:26
Thanks for the answer. Since it's a one-panel configuration, can I presume the total memory consumption to be that of the only panel, or does the component use more memory besides the panel shares?
SMP needs additional memory for JS engine and for internal usage, but it's safe to assume that panel is the one that contributes the most to memory usage (unless it contains nothing :P).
The memory impact of SMP will be close to zero (citation needed), if there are no SMP panels active.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-02 20:52:31
Hello @TheQwertiest, I am sorry, I have bad news: no way for me to install ever the v1.2.2-preview.
I am getting the same error.
I would like to try to remove the current version I have running:

Spider Monkey Panel v1.2.3-beta+61085bf2 by TheQwertiest
Based on JScript Panel by marc2003
Based on WSH Panel Mod by T.P. Wang

Build: 10:49:05, Nov 11 2019
Columns UI SDK Version: 6.5

But what about if then I cannot reinstall any?

Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-09 15:04:37
Created a basic website for SMP documentation - https://theqwertiest.github.io/foo_spider_monkey_panel
Notable features:
- Built-in script documentation (the one that is currently supplied with the component): https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/javascript_api
- Script showcase (more like script list currently, but I will work on that): https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_showcase
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-09 15:33:24
👍👍👍
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-09 17:14:04
Quote from:  console.log
on_size
Spider Monkey panel initialized
on_size (3 times)       <=======
UI initialized
foo_custom_database initialized
autoplaylist initialized
start up done (at least start up time is written here in the console log) <-----------------
possible playlist events
on_paint

One way or another, I always stumble on this multiple on_size() fire at start up. I never read other users having problems with it, so I wonder if I'm simply ignoring some document or some common good practice.
Some time ago I learnt that the full window width and height are not available until the last of the three events and consequently instructed my scripts to check the window size before making calculations on it. I relied on the assumption that the window size is either full or 0. But today I found out that the second on_size() sets the window to an intermediate measure, which my code was not expecting. Did the start up procedure change with one of the last updates? Or is it just me, finding out in dribs and drabs how things work ?
Working around such issues is quite easy, as long as I understand correctly what is going on under the hood. Clearly analyzing the console log and making guesses is not enough. Can anybody explain me once and for all how the panel initialization works and why? What is the safe way to initialize objects and variables with values relative to the window size?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: seongbin on 2019-12-09 18:33:00
Maybe a stupid question (non-programmer btw)....
Is there any difference between SMP and JScript or WSH while rendering text with GdiDrawText? Feels like it is slightly different in details especially for CJK characters, actually SMP has much better effect.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-09 23:19:51
Here's a javascript puzzle not strictly related to SMP, I hope it is not too off topic.

I'm working on a nested objects system, where each object is an item in an array property of a container object. The methods of the container object execute the method with the same name in the nested objects. This is done by calling another method - the forward() method in the code below - so the container constructor function has the following structure:
Code: [Select]
function Container(){	this.items = [obj1, obj2, obj3...];	this.method1 = (...args) => {this.forward('method1', ...args)};	this.method2 = (...args) => {this.forward('method2', ...args)};	this.method3 = (...args) => {this.forward('method3', ...args)};	...	this.methodN = (...args) => {this.forward('methodN', ...args)};	this.forward = (method, ...args) => {		this.items.forEach((item) => {if (method in item) item[method](...args)});	}}

Since the methods from 1 to N have the same pattern I thought I could make them perfectly alike and thus simply reference the forward() method for all. What I need is to ditch the "method" argument in the forward() method and retrieve it by code from the caller method's name. But it turns out it is harder than I thought. Ideally I would like to write something like:
Code: [Select]
function Container(){	this.items = [obj1, obj2, obj3...];	this.method1 = this.forward;	this.method2 = this.forward;	this.method3 = this.forward;	...	this.methodN = this.forward;	this.forward = ( ...args) => {		this.items.forEach((item) => {			let method = //...code to retrieve the caller*** method's name			if (method in item) item[method](...args)});	}}//***if this kind of code did work like I mean, the container's method would not be a caller anymore, just a reference.

It looks like such a typical scenario for javascript that I'm confident there must be a way, but everything I tried failed. Do you have any suggestion?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-10 10:28:54
It looks like such a typical scenario for javascript that I'm confident there must be a way, but everything I tried failed. Do you have any suggestion?
Retrieving caller information was deemed a problematic feature for multiple reasons:
- Makes some optimizations impossible.
- Easy to abuse to make code unreadable.
- (Web-specific) potential security vulnerabilities.

There is Function.caller (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller), which can be abused to get the name of the function. But this will not be performance friendly (constant regexp parsing) and this method is unavailable in strict mode anyway.

Maybe a stupid question (non-programmer btw)....
Is there any difference between SMP and JScript or WSH while rendering text with GdiDrawText? Feels like it is slightly different in details especially for CJK characters, actually SMP has much better effect.

No intentional changes on my side =)
The only thing I can think of, is that I target Windows 7 as a minimum supported OS, while WSH and JSP target Windows XP, so that could've affected the way GdiDrawText is called, theoretically.

Did the start up procedure change with one of the last updates?
Nope.

Working around such issues is quite easy, as long as I understand correctly what is going on under the hood. Clearly analyzing the console log and making guesses is not enough. Can anybody explain me once and for all how the panel initialization works and why?
Are you using SMP panel as a standalone CUI/DUI panel? Or is it a part of smth like PSS?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-10 16:22:37
There is Function.caller (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller), which can be abused to get the name of the function. But this will not be performance friendly (constant regexp parsing) and this method is unavailable in strict mode anyway.

Yes, I tried that and it actually crashed the panel, because indeed I am using strict mode. But then, why does this function I use for debugging purposes work in strict mode?
Spoiler (click to show/hide)

Retrieving caller information was deemed a problematic feature for multiple reasons:
- Makes some optimizations impossible.
- Easy to abuse to make code unreadable.
- (Web-specific) potential security vulnerabilities.

I read a bit about this topic in the last days, in search for a solution, and I understand that these caller methods are vestiges of a pre-named-functions era in javascript, but it is exactly the name of the function that I need to have, not the function itself, which is probably the only case when a caller method makes sense. I also understand how uncertain it is to rely on a "function name", which is actually not a property of the function, just one of many possible references to it. But when that reference is an object property, it is definitely more reliable.

Whatever. All in all it seems that the ECMA guys know what they are doing. The thesis that if you think you need the caller method, there is likely a better way to do what you are trying to do, turned out to be true, at least for me. As is often the case, posting the problem on the forum cleared my mind and I realized I actually don't need the method's name, I actually don't need all those methods at all, but just the forward method with an argument, from the head of the chain, so my container constructor is now something like this:
Spoiler (click to show/hide)

It might be a little meaningless out of context, but I got rid of several lines of code and the final result is a lot more concise than it would have been with a caller-like workaround. Sorry if this was a waste of time, but I just wanted to witness the wisdom of javascript constraints, which I was cursing until yesterday night, and blessing today for pushing me into better coding.

Are you using SMP panel as a standalone CUI/DUI panel? Or is it a part of smth like PSS?

I was using PSS, but since I don't need it (thanks for reminding me!), I removed it and tested it again, with CUI and with DUI. The on_size() callback is always triggered three times in a row, and the window size is always 0x0 on the first, full width x full height on the third and intermediate values in the second, but these are different with DUI, CUI and PSS.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-11 00:40:44
For reasons I don't understand, it only works with columns ui, maybe some more advanced coder can figure out why,

I still don't understand the reason, but at least now I know that to make it work in DUI I need to set the window dialog code to 4 (DLGC_WANTALLKEYS). At first I thought the reason was the default dlgcode in CUI, but I checked and with both UI, SMP has a default dlgcode set to 0. Can anybody explain me why DUI needs a different dlg code to take key events?

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zoumbro on 2019-12-13 06:14:31
dear developer(s)

I am facing the following message after installing the latest fsmp version.
I am using latest foobar 1.5 and I have attached a report of installed components.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-16 10:35:29
But today I found out that the second on_size() sets the window to an intermediate measure, which my code was not expecting.
I could not reproduce this behaviour, do you have a reproducible scenario?

Regarding repeated on_size calls: these are only invoked when the panel receives WM_SIZE message (except for one extra invocation which will be removed in the next version. These messages might be triggered by fb2k, by DUI, by CUI or by system itself. SMP just translates this native system message to JS callback.

I am facing the following message after installing the latest fsmp version.
I am using latest foobar 1.5 and I have attached a report of installed components.

You probably didn't install all the required fonts (which are listed in readme.md in samples folder).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-16 16:09:49
I could not reproduce this behaviour, do you have a reproducible scenario?

Yes, a very simple one: clean portable installation (v1.5.1 beta 2) with only two extra components: spider monkey panel and columns ui. No library, no playlists.
The columns ui layout is just one spider monkey panel, as a base, with this script:
Code: [Select]
function on_size(){    console.log("width: " + window.Width, "height: " + window.Height);}

And here's the console output on startup:
nk=msg=978394 date=1576492529]
Regarding repeated on_size calls: these are only invoked when the panel receives WM_SIZE message (except for one extra invocation which will be removed in the next version. These messages might be triggered by fb2k, by DUI, by CUI or by system itself. SMP just translates this native system message to JS callback.

I get it. After reading your explanation I recreated the above scenario without CUI and here's the console log:
Quote from: the console log
width: 0 height: 0
width: 1364 height: 653

The height is lower than CUI in the final size because of the toolbars.
So, it looks like the intermediate sizing is triggered by CUI. Problem solved. I don't need CUI actually, but for removing toolbars. BTW, replacing a whole interface only to get rid of the toolbars is kind of ridiculous, isn't it?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-16 20:33:21
Hello @TheQwertiest, I have a big problem with Foobar 1.5 beta 2 crashing at start while loading SMP.

I also tried the last nightly build having the same crash on start.
Probably the case to notify also Peter. I didn't do yet.

Attached the crash report files

Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zoumbro on 2019-12-17 08:29:29
But today I found out that the second on_size() sets the window to an intermediate measure, which my code was not expecting.
I could not reproduce this behaviour, do you have a reproducible scenario?

Regarding repeated on_size calls: these are only invoked when the panel receives WM_SIZE message (except for one extra invocation which will be removed in the next version. These messages might be triggered by fb2k, by DUI, by CUI or by system itself. SMP just translates this native system message to JS callback.

I am facing the following message after installing the latest fsmp version.
I am using latest foobar 1.5 and I have attached a report of installed components.

You probably didn't install all the required fonts (which are listed in readme.md in samples folder).

I have all fonts installed (Guifx v2 Transports, fontawesome-webfont,wingdings2.ttf and wingdings3.ttf).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-17 10:17:05
@AndreaT , a known issue that I've actually fixed already, but forgot to merge into master branch >_<
Will be up shortly (in a nightly build).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-17 10:39:13
Hello @TheQwertiest, thanks for the prompt reply.
Please, if you don't mind, kindly drop me a message (here or private) when the new Nightly Build is ready for testing.
Many thanks and kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-17 11:11:01
@AndreaT, nightly build with the fix is up.

@zoumbro , I was reminded by @marc2k3 (https://github.com/marc2k3) that it's a known (and fixed) problem in the script. Regrettably, there is no release build yet which has the fix. So, you can either download the nightly build (see OP for the link), or download and replace all the scripts manually (https://github.com/TheQwertiest/foo_spider_monkey_panel/tree/master/component/samples)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-12-17 21:45:56
Hello @TheQwertiest, well done! Now it works fine again. Many thanks. Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-19 19:18:06
I'd like to get back to this (https://hydrogenaud.io/index.php?msg=971543) clipping procedure, which as far as I understand is the SMP translation of this (https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/restricting-the-drawing-surface-in-gdi#see-also) windows GDI+ clipping technique. As far as clipping i concerned, it works as it should, but the text rendering sucks. I didn't realize this at first because I was working with white text on black background. In the code below, I added some text in the clipped region and changed the colours to make the problem visible.

Code: [Select]
include(fb.ComponentPath + "docs\\helpers.js");let font = gdi.Font("segoe UI", 16);let myRegion = new PaintRegion(100, 100, 200, 200)function on_paint(gr){	gr.FillSolidRect(0, 0, window.Width, window.Height, colours.DarkGray);	gr.GdiDrawText("TEST", font, colours.White,110, 70, 100, 20)    myRegion.paint(gr);}function PaintRegion(x, y, w, h){    this.x = x;    this.y = y;    this.w = w;    this.h = h;    this.paint = (gr) => {				gr.FillSolidRect(this.x, this.y, this.w, this.h, colours.Pink);        var clipImg = gdi.CreateImage(this.w, this.h)        var grClip = clipImg.GetGraphics();					grClip.GdiDrawText("TEST", font, colours.White, 10, 10, 100, 20)					grClip.DrawEllipse(100, 50, 200, 200, 2, colours.White);			        clipImg.ReleaseGraphics(grClip);        gr.DrawImage(clipImg, this.x, this.y, this.w, this.h, 0, 0, this.w, this.h)    }}

In the attached picture you can see the outcome. The first line of text on gray background is drawn with the regular graphics object passed by the on_paint callback, the one below, in the pink clipped region is drawn with the clipped graphics object. SetTextRenderingHint and SetSmoothingMode didn't help.

How can I avoid this blurred effect?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-20 00:36:44
How can I avoid this blurred effect?

So, apparently the problem is the DrawText function. Once more posting to the forum helped me find the answer. I finally found a case where you actually need the DrawString method.

P. S.
Upon reading some window .NET docs on GDI+ and TextRender, I have the impression that the use of DrawString is strongly encouraged, whereas I get the opposite idea from the SMP docs. Are the two methods actually the same? And what are the drawbacks of replacing DrawText with DrawString, anyway?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-20 10:01:32
Upon reading some window .NET docs on GDI+ and TextRender, I have the impression that the use of DrawString is strongly encouraged, whereas I get the opposite idea from the SMP docs. Are the two methods actually the same? And what are the drawbacks of replacing DrawText with DrawString, anyway?
DrawString is worse than DrawText in most cases. DrawText has better performance and better rendering unless used on a transparent surface (as mentioned in SMP docs).
One of the sources: https://stackoverflow.com/questions/1203087/why-is-graphics-measurestring-returning-a-higher-than-expected-number/6404811#6404811

Regarding your problem. Quote from docs (https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/GdiGraphics.html#GdiDrawText):
Quote
GdiDrawText
Provides faster and better rendering than GdiGraphics#DrawString.

Do not use this to draw text on transparent background or with GdiGraphics other than the one passed in on_paint callback: this will result in visual artifacts caused by ClearType hinting.
Use GdiGraphics#DrawString instead in such cases.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-12-20 14:01:12
DrawString is worse than DrawText in most cases. DrawText has better performance and better rendering unless used on a transparent surface (as mentioned in SMP docs).
One of the sources: https://stackoverflow.com/questions/1203087/why-is-graphics-measurestring-returning-a-higher-than-expected-number/6404811#6404811

Thanks, this was very, very useful.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: seongbin on 2019-12-28 00:51:02
Firstly, MERRY X MAS! and thx for the great component.
It looks like DrawImage() in SMP is generating left and top border by default. How can I avoid this?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-12-28 10:25:44
Firstly, MERRY X MAS! and thx for the great component.
It looks like DrawImage() in SMP is generating left and top border by default. How can I avoid this?
o/
What version of SMP are you using?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: seongbin on 2019-12-28 20:43:58
o/
What version of SMP are you using?
I am using v1.2.2-preview+0db3c6a4. I tried simply comment out the relevant line in JScommon.js as below, but the borders are still there in jssb.
Code: [Select]
function drawImage(gr, img, src_x, src_y, src_w, src_h, auto_fill, border, alpha) {	if (border) {//		gr.DrawRect(src_x, src_y, src_w - 1, src_h - 1, 1, border);	}}

-eidt-
I digged google a little bit, it looks like borders are generated during resizing images
https://mariusschulz.com/blog/preventing-ghost-borders-when-resizing-images-with-system-drawing
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: kowal24 on 2020-01-02 21:21:06
Hi
Today my AV shows info about virus in file foo_lastfm_img.vbs. Anyone have the same problem?

(https://i.imgur.com/KiD3xEp.jpg)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: seongbin on 2020-01-05 12:12:10
-eidt-
I digged google a little bit, it looks like borders are generated during resizing images
https://mariusschulz.com/blog/preventing-ghost-borders-when-resizing-images-with-system-drawing

NVM, simply resolved by setting interpolation mode as "0" in relevant functions.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-01-10 15:54:50
@seongbin , glad to hear that your problem was resolved. Sorry for the lack of answers - was on a vacation and (mostly) away from the internet...

@kowal24 , false-positive (you can view the code of the script to manually verify that).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2020-01-23 09:21:35
Hi,

I've got an issue related to search query and multi values tags.
I'm searching in my whole library the tracks by an artist simply named "bob".
I could do
fb.GetQueryItems(fb.GetLibraryItems(), "%artist% IS bob");
but then it won't return the tracks tagged with multi values, like "bob; nirvana".

In order to include the tracks tagged with multiple artists, I could do
fb.GetQueryItems(fb.GetLibraryItems(), "%artist% HAS bob");
but then it will return all tracks with bob inside their artist name, like bob dylan, and not all tracks by the artist simply named "bob".

Does someone there have an idea? Thanks!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-01-27 10:50:16
Does someone there have an idea? Thanks!
fb.GetQueryItems uses fb2k query rules. I.e. you can use and test this query in default CUI playlist_view search. So I think you are more likely to get a proper answer if you create a separate thread in General forum section.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-02-04 14:56:04
Version: 1.2.3
Changelog:
Spoiler (click to show/hide)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-02-04 14:58:51
Note: I've decided to make this Maintenance release, because a full Feature release is still far away from being ready...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-02-04 18:55:19
Reuploaded v1.2.3. It shouldn't crash anymore now =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: wcs13 on 2020-02-08 00:41:35
Hi :) Some time ago with WSH Panel component, I was using the "Thumbs" script by marc2003.
It's a nice script that displays not only a main pic, but several thumbs of other pics that you can select by clicking on them, etc.. Plus it's really customizable (e.g. I could edit lines 10 & 11 to change data folder and subfolders format).
So of course my question is : is there some port or equivalent script that I could use with Spider Monkey ? Thanks !
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MojoBass on 2020-02-08 04:18:42
Isn't this (https://github.com/marc2k3/smp_2003/blob/master/js/thumbs.js) Marcs smp version of his thumb.js? (not using it myself)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: mjm716 on 2020-02-08 05:47:47

So of course my question is : is there some port or equivalent script that I could use with Spider Monkey ? Thanks !

Yes Marc's old scripts are all ported to SMP and found in the default SMP install folder: foobar2000\user-components\foo_spider_monkey_panel\samples\complete
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: wcs13 on 2020-02-08 11:42:04
Got it :) Thanks MojoBass & mjm716 !

There is however one thing I can't get to work :
- With the old WSH script I could set a custom data folder, and then automatically download pics to that folder and subfolders. It worked perfectly.
- With the new SMP script I can set a custom folder structure (in my case it would be "D:\AUDIO\BIOS\artists\$meta(artist,0)"), and then the script displays the already existing pics... but there is no automatic download of new pics (e.g. when there are no pics yet, or where the number of existing pics is lower than the set limit). If I change "Custom folder" to "Last.fm artist art" I see a "Download now" menu option, but : - The download is manual, so I'd have to select "Download now" for every new song, which is painful for thousands of artists, - The pics then get downloaded to %foobar folder%\js_data\artists\ , not to my custom folder. Can I change this behaviour ? How ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-02-08 13:40:12 @wcs13 , marc2003 removed automatic download option (AFAIK people abused it by settings download limit too high, thus violating LastFM rules, which prompted LastFm to block marc's API key), you can probably restore it by comparing the old script with the new one and copying all the relevant changes. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-02-12 16:20:00 I've been thinking about this. Rather than removing auto-download, maybe this would have been more useful in marc's script ? Idea 1 : - Define two api_key variables : m_api_key = marc's one (somewhere in the middle of the script), and user_api_key = empty (to be filled by the user at the beginning of the script) - "Download now" would use m_api_key, but "Auto download" would use user_api_key, so it would result in an error until user enters a valid user_api_key Sure, an evil user could always try to tweak the script into using m_api_key for autoDL, but very few users would go through the hassle. Easier to just get a personal API Key and copy it in the very first lines of the script. Idea 2 : An even stricter solution : just define a single user_api_key variable (empty), so no DLs at all until user enters a valid key. But once he does, autoDL would work too. My point being : if you're a developer, please don't break script's functionality just because of some (ab)users. Stop giving the API Key if needed, but never break functionality. It harms the good guys, while at the same time any abuser with JS knowledge could restore function using marc's previous WSH script and keep abusing it. Anyway, I'll wait until somehow this function can be restored : I already have a personal API Key, but I know little about JS so I can't do all those changes on my own. :( Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: mjm716 on 2020-02-13 02:54:24 Anyway, I'll wait until somehow this function can be restored : I already have a personal API Key, but I know little about JS so I can't do all those changes on my own. :( It could be a loooong wait. WilB's absolutely amazing SMP/Biography script has better downloading capabilities and customization than Marc's script. I use them both myself. https://hydrogenaud.io/index.php?topic=112914.0 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-02-13 08:40:43 Last update of complete samples should be attached. Includes automatic download options for Thumbs script. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-02-13 10:24:37 @wcs13 , @mjm716 , actually marc2003 re-added automatic download to the Thumbs script yesterday (he also corrected my misinformation about LFM API key requirement: the script actually parses LFM site manually without using LFM API). But, regretfully, he deleted his GitHub account shortly afterwards =( @mjm716, I would say that one should use WilB's Bio script if they need everything in a single panel, and use marc2003's scripts if they want to separate various functionality in multiple different panels (e.g. thumbs and last.fm bio scripts). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-02-13 10:55:23 Last update of complete samples should be attached. Includes automatic download options for Thumbs script. Thanks! (esp. for providing .git as well) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Smurth on 2020-02-13 18:42:31 Hello, Is there a way to disable the default context menu (and NOT replacing it with another) ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-02-14 00:45:07 Quote from: mjm716 It could be a loooong wait Quote from: snotlicker Last update of complete samples should be attached. Includes automatic download options for Thumbs script. Quote from: TheQwertiest actually marc2003 re-added automatic download to the Thumbs script yesterday Wow guys, that was faster than I expected ! :)) I have indeed updated the SMP samples and now autoDL seems to work again. Thank you ! :) One question though : - In "last.fm artist art" mode, art is downloaded to %foobar folder%\js_data\artists - In "custom folder" mode, art isn't downloaded to the defined custom folder (ex : "D:\AUDIO\BIOS\artists\$meta(artist,0)" ). It just doesn't seem to be downloaded anywhere.
Am I doing something wrong ?

I'd really like the art to be downloaded to my big storage D: drive, and not to my small system C: drive.
Besides, I have several portable foobar installs, and I'd like them all to share the same art folder in order not to download art multiple times.
As a last resort, maybe I could edit the script and change the the default %foobar folder%\js_data\artists. Any hints on what line(s) I should edit ?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-02-14 12:17:25
Is there a way to disable the default context menu (and NOT replacing it with another) ?
Implement an empty on_mouse_rbtn_up callback that returns true. Corresponding docs: https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/module-callbacks.html#~on_mouse_rbtn_up
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Smurth on 2020-02-14 16:15:56
Implement an empty on_mouse_rbtn_up callback that returns true. (...)

Thank you very, very much ;)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: kutuzof on 2020-02-21 18:58:15
Greetings!
I am not good at scripting. I want to create a menu for switching DSP presets. There is a switching code for the output device, but when I replace with "fb.GetDSPPresets()" the menu remains the same.
Code: [Select]
function getDSPPresetsMenu(x, y) {	x = Buttons.top_l.left;	y = Buttons.top_l.top;    var menu = window.CreatePopupMenu();    var str = fb.GetDSPPresets();    var arr = JSON.parse(str);    var active = -1;    for (var i = 0; i < arr.length; i++) {        menu.AppendMenuItem(0, i + 1, arr[i].name);        if (arr[i].active) active = i;    }    if (active > -1) menu.CheckMenuRadioItem(1, arr.length + 1, active + 1);    var idx = menu.TrackPopupMenu(x, y);    menu;    if (idx > 0) fb.RunMainMenuCommand("Playback/DSP settings/" + arr[idx - 1].name);}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Smurth on 2020-02-26 16:26:36
Hello,

I'm having an issue with fb.IsMainMenuCommandChecked()

The code below allow me to successfuly change the settings - all the defined settings - but it fail to retrieve the state of the "Playback/order/..." stuff. II can't understand why. Foobar's bug or SMP's bug ?
Or me ?

Code: [Select]
		let menu = window.CreatePopupMenu();		let ent = ['Order/Default','Order/Repeat (playlist)','Order/Repeat (track)','Order/Random','Stop after current','Playback follows cursor','Cursor follows playback'];		for (var i = 0; i < ent.length; i++) {			menu.AppendMenuItem(MF_STRING, i+1, ent[i].replace('Order/',''));			if (fb.IsMainMenuCommandChecked('Playback/' + ent[i])) {				menu.CheckMenuItem(i+1, true);			}			if (i == 3){				menu.AppendMenuSeparator();			}		}		const idx = menu.TrackPopupMenu(x, y);		if (idx>0) {			fb.RunMainMenuCommand('Playback/' + ent[idx-1]);		}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Smurth on 2020-02-26 19:03:34
I'm having an issue with fb.IsMainMenuCommandChecked()
...

Sorry, I've missed plman.PlaybackOrder.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: wcs13 on 2020-02-27 23:51:04
- In "last.fm artist art" mode, art is downloaded to %foobar folder%\js_data\artists
- In "custom folder" mode, art isn't downloaded to the defined custom folder (ex : "D:\AUDIO\BIOS\artists\$meta(artist,0)" ). It just doesn't seem to be downloaded anywhere. Am I doing something wrong ? I'd really like the art to be downloaded to my big storage D: drive, and not to my small system C: drive. Besides, I have several portable foobar installs, and I'd like them all to share the same art folder in order not to download art multiple times. As a last resort, maybe I could edit the script and change the the default %foobar folder%\js_data\artists. Any hints on what line(s) I should edit ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-02-28 12:46:31 @kutuzof , regarding GetDSPPresets(): yep, that's a bug. Fixed in the nightly build. @Smurth , regarding IsMainMenuCommandChecked(): yep, that's a bug as well - this command didn't work properly for menu items that are hidden by default. Fixed in the nightly build. @wcs13 , in custom folder mode images are loaded from the folder provided by user, so it doesn't download anything. Folders for all marc's scripts are defined in js\helpers.js (search for let folders = {};). Beware that changing these paths will affect all scripts that are using said paths. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-02-28 16:28:19 @kutuzof , regarding GetDSPPresets(): yep, that's a bug. Fixed in the nightly build. Hi @TheQwertiest , concerning this GetDSPPresets() function, I can see that it is listed in the autocomplete entries, but I cannot find any reference in the docs. If it wasn't for @kutuzof 's post, I wouldn't know about it. Am I missing some source of information? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-02-28 18:15:48 Am I missing some source of information? Yep, you should've read it from my mind :D Anyways, it's indeed missing from docs. I'll add it soonish. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-02-28 19:24:28 Yep, you should've read it from my mind :D :) I see, so that's @kutuzof 's secret superpower. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-02-28 20:43:11 No super powers required. :-X https://github.com/kbuffington/foo_jscript_panel/blob/54fc020f09f3a9fb54bdbed8f3c1e6755e4ff8a6/component/docs/Interfaces.txt#L282 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-02-28 23:14:48 @wcs13 , in custom folder mode images are loaded from the folder provided by user, so it doesn't download anything. Folders for all marc's scripts are defined in js\helpers.js (search for let folders = {};). Beware that changing these paths will affect all scripts that are using said paths. It all works perfectly now. You made my day ! :D I'll remember that other scripts may use those paths, but so far I'm only using Marc's Thumbs and WilB's bio. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-02-29 01:45:23 BTW I have noticed what could be a glitch on marc's Thumbs script. It's easy to reproduce. Let's say %artist% = "Bryan Lee & The Jump Street Five" WilB's bio nicely creates a folder called "Bryan Lee & The Jump Street Five" and downloads relevant album art. However, marc's Thumbs creates a folder called "Bryan Lee & The Jump Street" and of course can't download any album art so the folder remains empty. Can somebody confirm this ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-02-29 05:09:13 Bug reproduced. Those scripts used a 3rd party Javascript library called lodash and the way you supply arguments to one of the functions got changed when upgrading from the old version 3 used with JSP and the newer version 4 bundled with SMP js\helpers.js line 197 replace Code: [Select] folder = folders.artists + _.truncate(a, 64); with Code: [Select] folder = folders.artists + _.truncate(a, { length : 64 }); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: anamorphic on 2020-02-29 05:32:08 I'll remember that other scripts may use those paths, but so far I'm only using Marc's Thumbs and WilB's bio. Also, I imagine that when we update SMP, all edited sample scripts will get overwritten to defaults? So perhaps copy the edited samples folder elsewhere for use, or make note of the changes you made, I guess. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-02-29 09:30:02 @snotlicker : thanks, it worked indeed :) @anamorphic : yes, I have already copied the edited samples AND made note of changes on separate txt files, just in case ;) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-02-29 12:11:19 I think I found another glitch : If %artist% is empty but %composer% is filled, WilB's bio creates a %composer% folder and downloads info, but marc's Thumbs does nothing. Any hints ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-03-02 10:20:16 @snotlicker , thanks! https://github.com/TheQwertiest/smp_2003/commit/c7d62119559fb1c46f4dcd43f74390b58f8f028e Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Anakunda on 2020-03-03 13:38:32 Hi, would be SpiderMonkey able to capture metadata from online source, apply them to audio tags, and eventually transfer the cover to album folder? The similar task what Discogs plugin does, just for custom source. If that's possible, could I get a hint what functions to use for it. Also I'd appreciate an existing script previously made for the same purpose as a template, if some. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Miltiades on 2020-03-14 21:15:09 Hallo there, I'm using (latest) foobar v.1.5.2. I have also SpiderMonkeyPanel, Biography and JScript Panel on latest version. It was working properly, as it should since yesterday at the afternoon: I can't see either artist pictures nor pictures from covers. I see only text (biography) but no pictures. Any suggestions please? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-01 14:14:00 I'm bumping this because it's been a month : If %artist% is empty but %composer% is filled, WilB's bio creates a %composer% folder and downloads info, but marc's Thumbs does nothing. Any hints ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-04-01 18:31:41 https://github.com/TheQwertiest/smp_2003/blob/master/js/helpers.js#L628 If all your tags are single value, you could replace it with %artist% as that has automatic fallbacks built in... https://wiki.hydrogenaud.io/index.php?title=Foobar2000:Title_Formatting_Reference#.25artist.25 If your tags are multi-value, you should use$meta to access the first value only...

Code: [Select]
$if2($meta(artist,0),$meta(composer,0)) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-03 03:09:45 Thank you. That worked indeed! My happiness is complete now :) Yes, I totally get your code. I'm quite OK at Titleformat but I suck at JS. I only needed to find the right line(s) in the right file(s), so thank you for pointing this one out! I really appreciate. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-03 14:10:31 New bug report, in helpers.js, line 511 : Code: [Select]  app.Namespace(10).MoveHere(file); Code: [Select] Error: Spider Monkey Panel v1.2.3 (Thumbs by marc2003)app.Namespace is not a functionFile: helpers.jsLine: 511, Column: 3Stack trace: _recycleFile@helpers.js:511:3 _thumbs/this.rbtn_up_done@thumbs.js:461:4 _panel/this.rbtn_up@panel.js:142:5 on_mouse_rbtn_up@<main>:49:9 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-04-04 05:32:56 That would be a component bug. For now you can replace that line of code with Code: [Select] _deleteFile(file) This bypasses the recycle bin though - files get deleted for good. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: mjm716 on 2020-04-04 16:37:01 I recently updated to 1.5.3 and have had a steady stream of crashes since. I can't really understand the reports, other than they seem to indicate SMP (and probably Marc's Thumb script)? (using v1.2.3) Can anyone help me decipher these? Code: [Select] CRASH:Error: Spider Monkey Panel v1.2.3 (Thumbs by marc2003)CheckMenuRadioItem failed:Index is out of boundsFile: thumbs.jsLine: 323, Column: 4Stack trace: _thumbs/this.rbtn_up@thumbs.js:323:4 _panel/this.rbtn_up@panel.js:85:4 on_mouse_rbtn_up@<main>:49:9Different CRASHError: Spider Monkey Panel v1.2.3 (Thumbs by marc2003)DrawImage failed:GdiPlus error: DrawImage failed with error (0x7): Win32ErrorFile: helpers.jsLine: 265, Column: 3Stack trace: _drawImage@helpers.js:265:3 _thumbs/this.paint@thumbs.js:92:23 on_paint@<main>:58:2different CRASH:Error: Spider Monkey Panel v1.2.3 (Thumbs by marc2003)DrawImage failed:GdiPlus error: DrawImage failed with error (0x7): Win32ErrorFile: helpers.jsLine: 280, Column: 3Stack trace: _drawImage@helpers.js:280:3 _thumbs/this.paint@thumbs.js:136:23 on_paint@<main>:58:2 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-04-04 17:14:27 Code: [Select] CheckMenuRadioItem failed:Index is out of bounds Pretty sure that's your fault for bypassing the available menu options and entering your own thumbnail size via the Properties dialog??? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: mjm716 on 2020-04-05 04:33:07 good lead - I do have one panel with custom thumb size. thank you, I'll see if that helps. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-04-06 12:15:23 New bug report, in helpers.js, line 511 : Code: [Select]  app.Namespace(10).MoveHere(file); It might be a casing error, try replacing Namespace with NameSpace. PS: component development is still on-going, if anyone was wondering =) The new (major) feature is just too non-trivial and it gets me frustrated all the time >_< Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-07 02:38:32 @TheQwertiest : casing error indeed! 'NameSpace' worked perfectly. Thanks, and please note the correction for future releases. Thanks again. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2020-04-09 22:45:07 PS: component development is still on-going, if anyone was wondering =) The new (major) feature is just too non-trivial and it gets me frustrated all the time >_< I love your PS. Take care. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: SUPERCOOLMAN on 2020-04-10 07:42:33 hit a crash. I think it's having issue with some high res large png images. foo_uie_albumart allows user to pick resolution resizing quality, not sure if it's this problem or just not happy with the type of png file(s) Code: [Select] File: helpers.jsLine: 287, Column: 1Stack trace: _drawImage@helpers.js:287:1 _thumbs/this.size/<@thumbs.js:55:6 r@lodash.min.js:5:356 Xe@lodash.min.js:67:63 _thumbs/this.size@thumbs.js:54:5 _thumbs/this.update@thumbs.js:483:3 _thumbs/this.metadb_changed@thumbs.js:167:3 on_metadb_changed@<main>:33:2 _panel/this.item_focus_change@panel.js:11:4 on_item_focus_change@<main>:25:2Spider Monkey Panel v1.2.3 (Thumbs by marc2003): initialized in 698 msOpening track for playback: "D:\ISU\OST_CD.cue" / index: 11Error: Spider Monkey Panel v1.2.3 (Thumbs by marc2003)Out of memory: 1754042880/1073741824 bytes overall I'm just looking for something that allows folder name with wildcard searching and allows multiple folders with cycling through all supported arts Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Fabio258 on 2020-04-10 16:26:14 I'm searching a playlist viewer that can be linked to a specific playlist like EsPlaylist. Is it possible with jsplaylist? I've tried but It seems auto-linked to the active playlist :( Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Air KEN on 2020-04-11 07:51:24 Hi. Picture cannot be displayed with Microsoft Store foobar2000 (not foobar2000 mobile). https://www.microsoft.com/store/apps/9PDJ8X9SPF2K Text only.Biography, thumbs ... Spider Monkey Panel and JScript Panel. Thanks for the help. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-11 14:46:31 Hi, another question about Thumbs script : I have noticed that downloaded images are often low-res, even when there are lots of hi-res images for the same artist on last.fm. For some artists there are hundreds of images available, but the component just seems to pick the first ones. Is there an option to either favor hi-res images, or the most upvoted ones, or to set a minimum res ? If not, it would be a nice add-on. Thanks ! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-04-12 08:53:51 Look at this HTML and tell me which images are low/hi res. Thanks. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-12 15:12:18 Hi @snotlicker , I just asked if there was an option that I wouldn't know about, because there are tons of things I don't know about. If it's not possible, then it's not possible, but there's no need to be ironic. Also, since I'm not a dev, I don't know if SMP scripts can check downloaded files. Maybe we could download an unknown pic, then once downloaded check its dimensions, and if it's too small, just trash it and download the next one. I don't know! https://www.tutorialrepublic.com/faq/how-to-get-current-image-size-in-javascript.php Thanks :) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Falstaff on 2020-04-12 17:30:12 I'm searching a playlist viewer that can be linked to a specific playlist like EsPlaylist. Is it possible with jsplaylist? I've tried but It seems auto-linked to the active playlist :( HI, as it is a script, you can modify jssplaylist to replace active playlist to a specific one, but it needs some changes to do that like replacing in script "plman.ActivePlaylist" with a variable that you have to set on init, by scanning existing playlists to find the index of the playlist you want to link to the playlist view (by playlist name testing imho ...) HTH ;) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-04-13 09:44:58 @SUPERCOOLMAN, it's an out of memory error. The script preloads all images from the folder without resizing them (so as to support dynamic size, e.g. when resizing player), so if there are a lot of big images, it might eat all of the available memory. It might be possible to avoid this issue by resizing images immediately after loading them, but this way there won't be a higher resolution image for dynamic resizing. @Air KEN , MS Store sandboxes their apps (by disabling some operations), in this case it might have disabled some internet related API used by SMP. Nothing I can do to fix that, aside from rewriting the whole networking stack (which I won't be doing any time soon). @wcs13 , it might be possible to implement such logic in the script (ignoring low-res images that is), but I'm currently prioritizing component development over script improvement. In other words it won't be fixed anytime soon, sorry. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-04-13 10:00:47 People getting out of memory errors with samples from the complete folder can open samples\complete\js\helpers.js and replace this function... Code: [Select] function _img(value) { if (_isFile(value)) { return gdi.Image(value); } else { return gdi.Image(folders.images + value); }} with Code: [Select] function _img(value) { let img; if (_isFile(value)) { img = gdi.Image(value); } else { img = gdi.Image(folders.images + value); } if (!img) return null; const MAX_SIZE = 1000; if (img.Width < MAX_SIZE && img.Height < MAX_SIZE) return img; const s = Math.min(MAX_SIZE / img.Width, MAX_SIZE / img.Height); const w = Math.floor(img.Width * s); const h = Math.floor(img.Height * s); return img.Resize(w, h);} Using the old function, I tested it with 8 large 5000px + images that take 40MB on disk but caused SMP to use nearly 900MB of ram according to window.PanelMemoryUsage After this change, the reported value was 22MB. edit: resizing doesn't come for free - there might be an apparent freeze for a second or 2 while it hogs the CPU!! YMMV. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-04-13 10:23:11 images that take 40MB on disk but caused SMP to use nearly 900MB of ram according to window.PanelMemoryUsage That's because images are loaded in memory as uncompressed BMP, so it takes much more memory than it could've (or should've). edit: resizing doesn't come for free - there is a performance penalty to be paid which might be noticeable?? YMMV. This is caused by resize operation being performed on the main thread. I was thinking of making it async or maybe incorporating it LoadImageAsync (i.e. load *and* resize), but thought that such functionality was not that needed... In long-term I'm planning to implement a new graphics back-end based on Direct2D (the support for current GDI/GDI+ back-end will remain), which should help with RAM utilization (amongst many other things). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Fabio258 on 2020-04-13 11:14:03 I'm searching a playlist viewer that can be linked to a specific playlist like EsPlaylist. Is it possible with jsplaylist? I've tried but It seems auto-linked to the active playlist :( HI, as it is a script, you can modify jssplaylist to replace active playlist to a specific one, but it needs some changes to do that like replacing in script "plman.ActivePlaylist" with a variable that you have to set on init, by scanning existing playlists to find the index of the playlist you want to link to the playlist view (by playlist name testing imho ...) HTH ;) Hi Falstaff, nice to see you here again :) Yes, if I was a programmer this can help me a lot, but sadly my programmer skills are slightly above 0 :'( And I don't want anyone to do the job for me for free. In jsplaylist there is already a menu with a list of existing foobar playlists. I'm sure that can be modified to lock the view to the selected playlist but I've no idea on how to do this and how long it takes. So, if there is someone who wants to do it for me, please send me a PM. Many thanks to all for this beautiful player and plugins Fabio Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: SUPERCOOLMAN on 2020-04-13 11:32:53 Using the old function, I tested it with 8 large 5000px + images that take 40MB on disk but caused SMP to use nearly 900MB of ram according to window.PanelMemoryUsage After this change, the reported value was 22MB. edit: resizing doesn't come for free - there might be an apparent freeze for a second or 2 while it hogs the CPU!! YMMV. ideally, script should generate only the small thumbnails when thumbnails is enabled. for main image, it should just keep a list of images file path found when current track's playback starts. script only need to load an image when being shown/drawn during current track's playback. there is already refresh/reload option when user want to refresh list of available images another way to do this would be detecting screen resolution at the beginning and just down scale all images larger than that to screen resolution or smaller before loading since screen resolution is your display upper limit This is caused by resize operation being performed on the main thread. I was thinking of making it async or maybe incorporating it LoadImageAsync (i.e. load *and* resize), but thought that such functionality was not that needed... In long-term I'm planning to implementing a new graphics back-end based on Direct2D (the support for current GDI/GDI+ back-end will remain), which should help with RAM utilization (amongst many other things). that would be a great improvement one of the problem with the old albumart is that it doesn't pre-load or cache images during current track's playback, so it causes fb2k to freeze for 1-3 seconds every time it cycles to a high resolution image Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-04-13 11:34:56 For just one script (thumbs), use JScript Panel. It has none of these issues. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: SUPERCOOLMAN on 2020-04-13 11:39:20 unfortunately, for another complex script, I had to freeze JSP at pretty old version due to newer JSP causing breakage. marc2003 has also completely removed his repositories, so this is the only current repository for the thumbs Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-04-13 12:07:04 What version? Just checked and anything newer than v1.1.6.1 should have thumbs included. Last.fm functionality will be broken in every version except the latest but since you're have issues with hi-res images, I'm assuming you're using custom folder mode which hasn't changed in years. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-04-13 12:11:56 another way to do this would be detecting screen resolution at the beginning and just down scale all images larger than that to screen resolution or smaller before loading since screen resolution is your display upper limit I think this is the easiest solution\workaround to your problem (coupled with the snippet @snotlicker posted above). But async resize would be needed to avoid fb2k freeze. I think I'll just add resizing to LoadAsync, coz I have a few huge album arts as well that I'm too lazy to resize, which cause fb2k to stutter every time they load... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Falstaff on 2020-04-13 17:09:53 Bug report: in panel script editor, "Replace all" makes freezing/looping the program when searched string is a word in lowercase and the new string is the same word in uppercase i.e: Replace "text" by "TEXT" i've just lost 50 minutes of works :( Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-04-13 17:34:44 That... should not happen =) I'll take a look tomorrow. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Falstaff on 2020-04-13 18:06:28 Thanks! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-14 03:57:35 @wcs13 , it might be possible to implement such logic in the script (ignoring low-res images that is), but I'm currently prioritizing component development over script improvement. In other words it won't be fixed anytime soon, sorry. Sounds great for me. Nobody's in a hurry. :) I'd love it if it can be achieved someday, so please put it in your to-do list and you'll get to it eventually. Many thanks for your work and your expertise! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: mjm716 on 2020-04-14 12:47:34 coz I have a few huge album arts as well that I'm too lazy to resize, which cause fb2k to stutter every time they load... I clean my images up (over 10GB of artists alone) in minutes using Agent Ransack (https://www.mythicsoft.com/agentransack/) and Image Resizer (https://www.bricelam.net/ImageResizer/). e.g. AR can search for image files of size> or dimensions> and the sortable results list can easily be batch resized by ctrl-click & IR Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-04-16 15:41:45 @Falstaff , Replace All is not working at all in the current version, REGEXP is borked as well. I'll fix it today\tomorrow. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-04-16 17:22:44 I clean my images up (over 10GB of artists alone) in minutes using Agent Ransack (https://www.mythicsoft.com/agentransack/) and Image Resizer (https://www.bricelam.net/ImageResizer/). e.g. AR can search for image files of size> or dimensions> and the sortable results list can easily be batch resized by ctrl-click & IR XnViewMP (https://www.xnview.com/fr/xnviewmp/) can do it too on its own, no need for two pieces of software : 1. Tools > Search (Add > File Size > Is greater than or equal to > 1000 > KiB) 2. Select all results 3. Right Click > Batch Convert (Add action > Image > Resize, then set all relevant options, everything is possible) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Bollerkopp on 2020-04-23 08:44:50 Hello, if I use some of the samples of the "complete" folder (e.g. "last.fm bio.js"), the panel crashes and I get the following error message: Quote Error: Spider Monkey Panel v1.2.3 (Last.fm Bio by marc2003) include failed: ActiveXObject_Constructor failed: WinAPI error: GetTypeInfo failed with error (0x80029c4a): Unknown error File: helpers.js Line: 588, Column: 11 Stack trace: @helpers.js:588:11 @<main>:5:1 I'm on Windows 10 64bit with foobar2000 v1.5.3.0. What could be the problem? Thank you very much in advance. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: hexenszene on 2020-04-26 09:24:26 Hope this is the right place to ask, but has the Spectrogram Seekbar that used to run on WSH Panel been upated for SM Panel? This is the old one: https://pastebin.com/6n0ZmTtB I know SoX is or would be required... Thanks! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: hexenszene on 2020-04-27 18:03:38 Another question... My SM Panels seem to be missing a font, so the down arrow isn't displaying properly. See here: https://imgur.com/a/FHia3X7 Does anyone know how to resolve this? And last but not least, Marc2003 used to have a Last.fm script for WSH Panel that allowed you to see "top tracks" and "top albums" for an artist. Has this been updated for SM Panels yet? Thanks all. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-04-28 10:12:34 @Bollerkopp , not sure, why you are getting this error. The library in question (Mshtml.dll) should be available on all supported Windows systems. Are you using a norrmal fb2k or a fb2k from Windows Store? There were reports about issues in Windows Store version. @hexenszene , Quote has the Spectrogram Seekbar that used to run on WSH Panel been upated for SM Panel? AFAIK, no. Quote My SM Panels seem to be missing a font have you installed Font Awesome as per readme? Quote And last but not least, Marc2003 used to have a Last.fm script for WSH Panel that allowed you to see "top tracks" and "top albums" for an artist. Has this been updated for SM Panels yet? complete/last.fm similar artists + user charts + recent tracks.js @Falstaff , regretfully, the fix is still not ready. Hopefully I'll have enough free time and energy to complete the fix soon (it's 95% ready). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: hexenszene on 2020-04-28 13:36:50 @Bollerkopp , not sure, why you are getting this error. The library in question (Mshtml.dll) should be available on all supported Windows systems. Are you using a norrmal fb2k or a fb2k from Windows Store? There were reports about issues in Windows Store version. @hexenszene , Quote has the Spectrogram Seekbar that used to run on WSH Panel been upated for SM Panel? AFAIK, no. Quote My SM Panels seem to be missing a font have you installed Font Awesome as per readme? Quote And last but not least, Marc2003 used to have a Last.fm script for WSH Panel that allowed you to see "top tracks" and "top albums" for an artist. Has this been updated for SM Panels yet? complete/last.fm similar artists + user charts + recent tracks.js @Falstaff , regretfully, the fix is still not ready. Hopefully I'll have enough free time and energy to complete the fix soon (it's 95% ready). Thanks for the help. I had looked for a readme in the folder but somehow missed it. Issue solved. Regarding the script "complete/last.fm similar artists + user charts + recent tracks.js" -- this doesn't seem to have "top albums" or "top tracks" in it. The only choices seem to be "last.fm user charts", "recent tracks", and "similar artists". Am I missing something? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MojoBass on 2020-04-28 20:00:00 Regarding the script "complete/last.fm similar artists + user charts + recent tracks.js" -- this doesn't seem to have "top albums" or "top tracks" in it. The only choices seem to be "last.fm user charts", "recent tracks", and "similar artists". Am I missing something? The Youtube Track Manager (YTTM, see here (https://hydrogenaud.io/index.php?topic=105522.100)) is listing top albums and top tracks out of the box. Runs as well on SMP. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: hexenszene on 2020-04-30 13:44:47 Regarding the script "complete/last.fm similar artists + user charts + recent tracks.js" -- this doesn't seem to have "top albums" or "top tracks" in it. The only choices seem to be "last.fm user charts", "recent tracks", and "similar artists". Am I missing something? The Youtube Track Manager (YTTM, see here (https://hydrogenaud.io/index.php?topic=105522.100)) is listing top albums and top tracks out of the box. Runs as well on SMP. This is awesome! Thank you! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Falstaff on 2020-04-30 17:15:45 @Falstaff , regretfully, the fix is still not ready. Hopefully I'll have enough free time and energy to complete the fix soon (it's 95% ready). *waits* ;) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-05-06 15:46:21 @Falstaff , should be fixed (hopefully) in the latest nightly build. What a PITA it was... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Falstaff on 2020-05-10 11:14:19 thanks, i'll test asap Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-05-29 04:46:45 @TheQwertiest I was building foo_spider_monkey_panel just fine and then I upgraded to VS2019 - 16.6, and the kmeans code throws errors wherever ranges::... is used. I think this is probably fixed by bumping up the range submodule dependency, but it looked like you were purposefully using an older version. Am I out of luck here? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-05-29 19:45:53 @MordredKLB , haha, well I've updated my VS as well and it indeed fails to build, but not in range-v3 part :P What is the commit that your range submodule is on? (cd submodules/range & git status ). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-05-30 18:31:42 @MordredKLB , haha, well I've updated my VS as well and it indeed fails to build, but not in range-v3 part :P What is the commit that your range submodule is on? (cd submodules/range & git status ). Well, After rebasing last night to get your 16.6 changes, everything is good again, and DEBUG builds just fine. I still can't build release versions though. I'm getting dozens of these 3 errors which shows me they're all related, but I can't figure out where the mismatch is coming from: Code: [Select] LNK2038 mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in abort_callback.objLNK2038 mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MT_StaticRelease' in abort_callback.objLNK2001 unresolved external symbol __CrtDbgReport Also, when I try and use the debug build I made, foobar tells me I have missing dependencies. This is why I should stick to JavaScript :D Edit: I'm realizing now that I can probably use your "pack_component.bat --debug" script to build the debug component, which I guess is really all I need to be able to do. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-05-30 19:03:04 Seems like your solution has a mix of statically linked and dynamically linked projects. They all need to be the same. edit: and debug/release mixed up too?? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-05-30 19:17:59 Seems like your solution has a mix of statically linked and dynamically linked projects. They all need to be the same. edit: and debug/release mixed up too?? Yeah, it's weird. I haven't touched any of that stuff either. Fresh pull, run setup.py, open the .sln file and attempt to build release. All the components are set to RELEASE as well. Either way, I can now build a debug component and that's what matters. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-05-30 19:44:31 You have to "Rebuild" the project when you change configuration. This is caused by some *make based dependencies (scintilla, lexilla), which output binaries to the same path in Release and Debug configuration (and they do not detect automatically the change in configuration to trigger the rebuild). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-05-30 19:53:05 The current version of Scintilla now includes a VS project file for lexilla which makes it easier. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-05-30 19:57:15 Thanks! I'll look into it. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-05-30 20:01:47 @snotlicker , it seems that these projects can only produce dynamic libraries, so it's not really suitable for SMP =( Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-05-30 20:22:13 I normally use dynamic but did a quick test with static and it compiles and works just fine?? Perhaps you need to update your linker settings to remove the .lib file previously generated by nmake?? edit: here's a screenshot of my own project - note the increased file size on the right! https://i.imgur.com/5CX6MTc.png Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-05-30 20:34:10 I normally use dynamic but did a quick test with static and it compiles and works just fine?? *.lib file that is produced by Scintilla.vcxproj is an export library. So if you link against it, it will actually link you against corresponding *.dll. You can test this by removing said *.dll file (the program should crash or disable the component once it tries to load the component library)). : https://i.imgur.com/JT8l35w.png As you can see *.lib has the size of only 2KB vs 2MB of *.dll. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-05-30 21:05:23 You have to "Rebuild" the project when you change configuration. This is caused by some *make based dependencies (scintilla, lexilla), which output binaries to the same path in Release and Debug configuration (and they do not detect automatically the change in configuration to trigger the rebuild). Ugh, should have thought to try that since it was clearly a release/debug mismatch. It's getting close to a decade since I worked professionally in VS/C-development so I've forgotten a few tricks. Thanks for merging that PR! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-06-02 07:20:59 @snotlicker , it seems that these projects can only produce dynamic libraries, so it's not really suitable for SMP =( Since I was locked on version 4.3.3, I didn't understand this issue but I guess you were on latest commit when you tried. Since a new version was released yesterday, I encountered the same issue and reported it here... https://groups.google.com/forum/#!topic/scintilla-interest/vnegGNO6nKw It has now been fixed in version 4.4.2. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: APECR on 2020-06-06 00:35:45 Code: [Select] image_cache = function () { this._cachelist = {}; this.hit = function (metadb) { var img = this._cachelist[metadb.Path]; if (list.drag_stop && typeof img == "undefined") { if(!cover.load_timer) { cover.load_timer = window.SetTimeout(function() { utils.GetAlbumArtAsync(window.ID, metadb, 0, true, false, false); cover.load_timer && window.ClearTimeout(cover.load_timer); cover.load_timer = false; }, 20); }; }; return img; }; this.getit = function (metadb, track_type, image) { var img; var quotient = (panel.flat_mode) ? 2 : 12; if(cover.keepaspectratio) { if(!image) { var pw = (cover.w+cover.margin*quotient); var ph = (cover.h+cover.margin*quotient); } else { if(image.Height>=image.Width) { var ratio = image.Width / image.Height; var pw = (cover.w+cover.margin*quotient)*ratio; var ph = (cover.h+cover.margin*quotient); } else { var ratio = image.Height / image.Width; var pw = (cover.w+cover.margin*quotient); var ph = (cover.h+cover.margin*quotient)*ratio; }; }; } else { var pw = (cover.w+cover.margin*quotient); var ph = (cover.h+cover.margin*quotient); }; // item.cover_type : 0 = nocover, 1 = external cover, 2 = embedded cover, 3 = stream if(track_type!=3) { if(metadb) { img = FormatCover(image, pw, ph); if(!img) { img = nocover_img; //item.cover_type = 0; } else { //item.cover_type = 1; }; }; } else { img = streamcover_img; //item.cover_type = 3; }; this._cachelist[metadb.Path] = img; return img; };}; Help convert Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-10 17:39:14 Version: 1.3.0 Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.3.0 Changelog: Spoiler (click to show/hide) Detailed description of API changes: https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/api_changes/#v130 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-07-10 18:46:00 SetFont doesn't work. Code: [Select] tooltip.SetFont is not a function Pre-existing methods like SetMaxWidth still work. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-12 00:05:34 I'm seeing phantom tooltips that keep coming back after a script crashes and you reload it. I maxed out at 5 visible on top of each other at the same time. No real rhyme or reason I can tell to why they show up (or what values they have), but switching to foobar from another tab causes them to show again. Seems like on a script crash Tooltip.Deactivate() might need to be called internally? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-12 07:04:47 I discovered this evening that gdi.LoadImageAsync can return the same task ID at certain times which was a serious problem when I was attempting to load two large images somewhat simultaneously and then check then check the IDs in the callback. Was pretty simple to migrate over to LoadImageAsyncV2 (which is much cleaner as well!) but still kind of a confusing problem. I'm also running into a memory leak when doing window.Reload(). I tried some pedantic stuff to reproduce but it seems garbage collection works fine, except in my theme. My foobar starts at around 250MB, and adds 10-20MB (seems somewhat dependent on size of the active playlist) each time I do a window.Reload(). Eventually foobar is using 1.3TBs and I get error messages like this immediately after my theme loads and I have to restart foobar: Code: [Select] Error: Spider Monkey Panel v1.3.0 (Georgia v2.0.0 by Mordred)Out of memory: 4057804/1073741824 bytes Still trying to figure out if there's something I can do to minimize things, or not. Edit: Seems I can mitigate things somewhat by setting playlist = null; and all of WillB's library objects to null before doing window.Reload(). Somehow it seems objects in the global namespace get orphaned references on a window.Reload... and I have a lot of stuff in the global namespace. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-12 12:10:15 SetFont doesn't work. Haha, welp, that's what I get for being lazy and not testing things properly =) Thanks for reporting. I'm seeing phantom tooltips that keep coming back after a script crashes and you reload it. Strange, that should not happen. I'll take a look if I can reproduce it. I discovered this evening that gdi.LoadImageAsync can return the same task ID at certain times Do you mean that that LoadImageAsync() returns the same ID when ran serially? E.g. Code: [Select] ids = []for (path in paths){ ids.push[gdi.LoadImageAsync(path)];}// ids not unique Task ID is just an object's memory address. The only way they could have the same id (in theory) is when the memory is reused (which is possible only if the previous task was finished and handled in the callback). I'm also running into a memory leak when doing window.Reload(). Still trying to figure out if there's something I can do to minimize things, or not. Regretfully, it's nearly impossible to fix such leaks without at least somewhat minimal repro scenario. Try downloading debug version of SMP, enable GC zeal (https://theqwertiest.github.io/foo_spider_monkey_panel/docs/for_developers/component_development_tips/#test-with-gczeal) and see if the memory leak is still there. Note: GC zeal will tank the performance, so it might take some time for the script to load. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-12 12:48:00 @snotlicker , fixed in the Nightly build. @MordredKLB , I've fixed the ghost tooltip in the Nightly build. Can you check if it fixes your memory leak as well? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-12 17:18:53 @snotlicker , fixed in the Nightly build. @MordredKLB , I've fixed the ghost tooltip in the Nightly build. Can you check if it fixes your memory leak as well? JFC, it was the god damned tooltip! Now I can spam the Reload() button on my theme, get memory up to 500MB, and it drops back down to 225-230ish within a few seconds. Also easy to verify since if I cause an error in the theme, memory usage drops back to a flat 207MB every time. I can't believe it. Ghost tooltip issue is also fixed. Thanks so much. :) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-12 20:41:58 Not to be one of those people, but I noticed that ESR 78.x was released a few days ago. How difficult is the jump from 68 to 78? I wouldn't have even noticed, but I was rewriting some of my stuff using the class syntax and found out that I got a "fields are not currently supported" crash when trying to use class field notation. No big deal at all, I was just surprised to discover that the ESRs only release once a year or so. One other question I've got, I've added the foo_spider_monkey_panel.js to my VSCode project, and it picks up types correctly for everything except window which gives me the following type error for every method: "Property 'RepaintRect' does not exist on type 'Window & typeof globalThis'." Any way around that? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-13 10:53:52 How difficult is the jump from 68 to 78? Dunno. SM devs do not care much for API stability (or MSVC compatibility), so it might be anything between a simple SM recompile or a full-blown SMP rewrite. Anyway, I won't start migrating to ESR78 before I finish the ConfigureV2 rewrite (which will take a loooong time). Any way around that? The problem is that window object is a built-in JS object, which causes conflicts with SMP definitions. There *is* probably a way to work around that, but I don't have any ideas =) PS: If you *do* find a workaround, plz message me, so I could add it to the docs. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-13 12:13:40 @MordredKLB , try smth like this: Code: [Select] { "compilerOptions": { // this is needed to suppress built-in browser objects (window, various DOM objects and etc) "lib": ["es2019"] }, "include": [ // project files "**/*.js", // docs "../../user-components/foo_spider_monkey_panel/docs/js/*.js" ],} Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-13 16:04:58 @MordredKLB , try smth like this: Code: [Select] { "compilerOptions": { // this is needed to suppress built-in browser objects (window, various DOM objects and etc) "lib": ["es2019"] }, "include": [ // project files "**/*.js", // docs "../../user-components/foo_spider_monkey_panel/docs/js/*.js" ],} Yup, that's what worked for me. BTW, I've made a ton of changes to the JSDoc stuff to fix VSCode false positives. Should I submit a PR for that? Not sure if everything currently works okay in intelliJ. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-13 16:57:11 Yup, that's what worked for me. BTW, I've made a ton of changes to the JSDoc stuff to fix VSCode false positives. Should I submit a PR for that? Not sure if everything currently works okay in intelliJ. Sure, I will take a look. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-14 15:53:18 I discovered this evening that gdi.LoadImageAsync can return the same task ID at certain times which was a serious problem I've tried to load 1000 images multiple times and didn't manage to reproduce the problem. Are you sure that the task id collision happened before it was utilized in on_load_image_done()? I.e. reuse of task id can only happen after the task_id is consumed by on_load_image_done() (which makes said task_id unused and available for further usage). : Nvm, reproduced and fixed. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-14 22:47:11 Remade script showcase page. Now it has screenshots and stuff! Link: https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_showcase Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-07-14 23:12:18 Thanks to your screenshot, just spotted a bug in the Properties script where subsong index is undefined. This is because of case sensitivity again... https://github.com/TheQwertiest/smp_2003/blob/7fc1d75cd73081e3a83cb16e6af0ef2405342150/js/list.js#L983 panel.metadb.Subsong should be panel.metadb.SubSong Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-15 10:49:07 Thanks to your screenshot, just spotted a bug in the Properties script where subsong index is undefined. Haha, nice catch =) Btw, could you help with the Last.fm Loved Tracks Manager script screenshot (I can crop it myself if needed) and/or description, please? I've never used Last.Fm for anything other than scrobbling... PS: It also appears that track info + seekbar + buttons script is borked, both on SMP and JSP. Hopefully, I have enough JS knowledge left to fix it :D Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-07-15 11:24:22 How is the track info+seekbar+buttons borked? I'm sure you know about the font requirements for the buttons. Perhaps your panel is far too big? Ideal height is around 60-80px The behaviour of the seekbar where if you move your mouse too far away while dragging and the grip is released... that's by design. (https://i.imgur.com/zaarAf5.png) edit: the last.fm lover script has this description inside it... Code: [Select] /*This script makes use of the Spider Monkey "Playback Stats" database to importand store loved tracks from Last.fm. Each loved track will have the value of%smp_loved% set to 1. You can access this through all other components/search -it works in the same way as "foo_playcount" - all values are stored in a databasefile and no files are tagged. Each record is bound to "%artist% - %title%" socommon tracks across different albums will share the same loved status. Right clickthe heart iocn to set your Last.fm username and authorise the script through yourbrowser. You can then import all your loved tracks and then use the heart iconto love/unlove tracks.*/ edit2: Of course the glaring error in that text is that you won't see a heart icon until AFTER you've configured your username and authorised through your browser. Until, then you'll see a little red exclamation mark. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: VlaKor on 2020-07-15 14:47:40 Btw, could you help with the Last.fm Loved Tracks Manager script screenshot (I can crop it myself if needed) and/or description, please? I've never used Last.Fm for anything other than scrobbling... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-16 13:53:40 Perhaps your panel is far too big? Ideal height is around 60-80px Yep, that was it =) edit: the last.fm lover script has this description inside it... Thanks! @VlaKor , thank you as well =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: jazzthieve on 2020-07-16 18:40:53 Speaking of Last.fm Loved Tracks Manager, is there a way to indicate in playlist with a value which tracks are loved? The only way to see is to go to the lastfm website or when a track is playing. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-16 19:05:25 @jazzthieve , if your playlist supports the display of custom tags, you can use %smp_loved% to get the value for the track (1 - loved, 0 - not really...). E.g. $ifequal(%smp_loved%,1,♥,).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: jazzthieve on 2020-07-16 19:43:54
Great, thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-07-18 13:14:52
Version: 1.3.1
Changelog
Hotfix for v1.3.0 (see changelog above (https://hydrogenaud.io/index.php?topic=116669.msg985305#msg985305))
Spoiler (click to show/hide)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2020-07-21 06:32:04
Haven't noticed any issues with 1.3.1. Thanks for being so responsive.

In my playlist, I've got hyperlinks that will create/replace the current playlist with a new search based on what you clicked on. I.e. you click on the artists name and the playlist just shows all songs by that artist. It bugged me that if I was playing a song by Tool for instance, and clicked on the artist name, calling plman.ClearPlaylist(pl) would also lose the playing status of the current playing song (i.e. it wouldn't show as being played anymore even though it's metadb was in the contents of the playlist).

So I devised this workaround to remove everything from the playlist except what was being played, then add the contents of the search back in:

Code: [Select]
const pl = plman.FindOrCreatePlaylist('Search', true);if (pl === plman.PlayingPlaylist && plman.GetPlayingItemLocation().PlaylistIndex === pl) {	plman.ClearPlaylistSelection(pl);	plman.SetPlaylistSelection(pl, [plman.GetPlayingItemLocation().PlaylistItemIndex], true);	plman.RemovePlaylistSelection(pl, true);	const playing = new FbMetadbHandleList(fb.GetNowPlaying());	handle_list.Sort();	const handle_copy = new FbMetadbHandleList(handle_list);	handle_copy.MakeIntersection(playing);	if (handle_copy.Count === 0) {		plman.ClearPlaylist(pl);	} else {		handle_list.MakeDifference(playing);	}	plman.InsertPlaylistItems(pl, 0, handle_list);} else {	// nothing playing or Search playlist is not active	plman.ClearPlaylist(pl);	plman.InsertPlaylistItems(pl, 0, handle_list);}

This works, but it seems incredibly hacky to me, and is hard to read. Is there a better/another way to remove items from a playlist than using RemovePlaylistSelection, or otherwise do this?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2020-07-21 08:02:49
Not sure modifying the contents of any existing playlist is the way to go if other people are using this?? To be safe, I'd be sending the contents of the query to a new playlist every time.

But if you really want to remove the playing track from the handle list of results, use BSearch to find its index and remove it.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-07-21 10:45:25
@MordredKLB , it's just the way fb2k works - played item is bound to the playlist it's playing on. If you clear a playlist then it's no longer bound to it (from fb2k point of view). So, yeah. The only way you can preserve this connection is by removing all other items like you currently do (but you can simplify it a bit via BSearch as suggested by @snotlicker ).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2020-07-21 16:34:10
Not sure modifying the contents of any existing playlist is the way to go if other people are using this?? To be safe, I'd be sending the contents of the query to a new playlist every time.

But if you really want to remove the playing track from the handle list of results, use BSearch to find its index and remove it.
It uses a specific playlist each time. Think of it like the CUI "Filter" playlist, or WillB's "Library Playlist". When you make a new selection the contents of that specific playlist are always replaced.

I want to do the opposite of removing the playing song. :) I want to see if the currently playing song is in the results of the search, and if so, remove everything else and then add the results of the search.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2020-07-21 16:35:35
@MordredKLB , it's just the way fb2k works - played item is bound to the playlist it's playing on. If you clear a playlist then it's no longer bound to it (from fb2k point of view). So, yeah. The only way you can preserve this connection is by removing all other items like you currently do (but you can simplify it a bit via BSearch as suggested by @snotlicker ).
I'm not sure how BSearch helps since I've already got the index from plman.GetPlayingItemLocation().PlaylistItemIndex.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2020-07-21 17:00:10

Code: [Select]
	const playing = new FbMetadbHandleList(fb.GetNowPlaying());	handle_list.Sort();	const handle_copy = new FbMetadbHandleList(handle_list);	handle_copy.MakeIntersection(playing);	if (handle_copy.Count === 0) {		plman.ClearPlaylist(pl);	} else {		handle_list.MakeDifference(playing);	}

...but maybe I have no idea what you're doing at all. If whatever it's supposed to do works, just leave it and forget I said anything. :D
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2020-07-21 17:28:28

...but maybe I have no idea what you're doing at all. If whatever it's supposed to do works, just leave it and forget I said anything. :D
I gotcha. Sorry I misread what you were saying earlier. This is much cleaner now:

Code: [Select]
handle_list.Sort();const index = handle_list.BSearch(fb.GetNowPlaying());if (pl === plman.PlayingPlaylist && plman.GetPlayingItemLocation().PlaylistIndex === pl && index !== -1) {	// remove everything in playlist except currently playing song	plman.ClearPlaylistSelection(pl);	plman.SetPlaylistSelection(pl, [plman.GetPlayingItemLocation().PlaylistItemIndex], true);	plman.RemovePlaylistSelection(pl, true);	plman.ClearPlaylistSelection(pl);	handle_list.RemoveById(index);} else {	// nothing playing or Search playlist is not active	plman.ClearPlaylist(pl);}plman.InsertPlaylistItems(pl, 0, handle_list);
Thanks!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2020-07-24 06:12:21
So I've noticed something kind of annoying with Georgia in FSM. When I start up foobar, everything has to spin up as my library loads and FB checks for changes. At the same time FSM is trying to parse my theme, and it's not uncommon to get a "this script is taking too long would you like to kill it" message. It appears that when the dialog is up, FSM freezes the scripts so even though they'd become responsive by the time you have a chance to click continue/kill it doesn't happen. Is there some way to increase the timeout before this warning when foobar is starting up... or not pause the scripts and clear the dialog if they do become responsive again?

Alternatively, is there something I can do in my scripts at startup to prevent this from happening?

BTW, don't know if it matters but my configuration is just a single include of a georgia-theme.js file, and that georgia-theme.js file is what actually includes all the js files for the theme. Figured that would give me more flexibility when updating the theme to add/remove files at will, but maybe the nested includes cause issues?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2020-07-24 11:14:40
Is there some way to increase the timeout before this warning when foobar is starting up...
Nope, won't be changed.

Quote
or not pause the scripts and clear the dialog if they do become responsive again?
That would be neat. I'll see if it's possible to do this.

Alternatively, is there something I can do in my scripts at startup to prevent this from happening?

The proper way to avoid holding stuff for long time would be to make initialization segmented, which would yield the control after each segment is completed (with smth like a progress bar). E.g.
Code: [Select]
// This is pseudo-codeis_initializing = true;function on_paint() {  if (is_initializing) {    print_loading_in_progress();  }  else {    print_normal_stuff();  }}function init_short(){  // basic init that doesn't hold for long}async function init_long() {  while (has_stuff_to_do) {     let promise = new Promise((resolve) => {       stuff_to_do = get_current_init_part();       stuff_to_do.do();       resolve(stuff_to_do.id)     });     stuff_id = await promise; // this will yield the execution     console.log($(stuff_id) done); } is_initializing = false;}init_short();init_long(); Figured that would give me more flexibility when updating the theme to add/remove files at will, but maybe the nested includes cause issues? The panel is considered a single script. I.e. it doesn't matter if it uses include() or just has everything inlined. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-24 17:39:49 I might try some tests with async/await wrapping includes. The warning seems to be entirely dependent on whether my hard drives need to spin up first... something I haven't been able to get to happen today. If the HDD is spinning, FSM loads my theme in <300ms at startup. Refreshing the panel after foobar has started takes about 20ms, so it's not that the script is actually slow. BTW, I stupidly had clicked the "don't show me this again" checkbox. Is deleting the foo_spider_monkey.dll.cfg good enough to reset that? It didn't reset the panel configuration so some data is being stored elsewhere at least. Edit: Rebooted my computer and got this to happen again. Async processing of files won't help the situation. I verified the file it had hung on last time, and it's the very second file I include, and it died at line 70, where I define the RGB helper function. Not exactly a tight loop. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2020-07-26 12:39:47 Using; handle_list.AttachImage(img_path, 0) If img_path contains ( or ) then image file is not found. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-07-26 12:58:18 You sure? Just tested and it works exactly as expected with () in the filename. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2020-07-26 13:45:52 Hi snotlicker Thanks for the quick response. You are correct and I'm guilty of such a stupid js school-boy error. Too embarrassed to tell what I'd done wrong. All working now. Thanks. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-26 14:06:52 BTW, I stupidly had clicked the "don't show me this again" checkbox. Is deleting the foo_spider_monkey.dll.cfg good enough to reset that? It didn't reset the panel configuration so some data is being stored elsewhere at least. "don't show me this again" options is fb2k-instance-local. Meaning that it only affects the current process of fb2k and it does not persist across different fb2k launches. @ your "hanging" problem: I'm trying to make "Slow script" dialog async, so that it would not halt the script execution. But I don't think I can do anything other than that. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-26 17:10:23 Does that mean you could also hide the dialog again, once things become responsive again, or no? Even if not it'd be a big improvement since users would be able to see the theme load behind the dialog. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-27 09:53:00 Does that mean you could also hide the dialog again, once things become responsive again, or no? Yes. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2020-07-27 14:15:35 I'm trying to process selected files from a playlist. Firstly I want to convert them and I'm using: fb.RunContextCommandWithMetadb("Convert/mp3 tablet",handle_list); then I want to embed the album cover. My problem is the the RunContextCommand doesn't block so I need an event that is raised when all the files have been converted. Any ideas? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-27 14:28:46 @Black_Over_Bills_Mothers , that's just the way fb2k API works. Hence can't do much if the invoked command is non-blocking :\ Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: fbuser on 2020-07-27 16:44:51 I'm trying to process selected files from a playlist. Firstly I want to convert them and I'm using: fb.RunContextCommandWithMetadb("Convert/mp3 tablet",handle_list); then I want to embed the album cover. My problem is the the RunContextCommand doesn't block so I need an event that is raised when all the files have been converted. Any ideas? In general you could use something like the code below. You need to replace <get handleList> and <do the processing for metaDb> with valid code and you might need to play a little bit with the timings. Code: [Select] const handleList= <get handleList>; fb.RunContextCommandWithMetadb("Convert/mp3 tablet",handleList); const processItem=() => { if(!handleList.Count) return false; const metaDb=handleList[0]; <do the processing for metaDb> handleList.RemoveById(0); return Boolean(handleList.Count);};() => { if(!processItem()) return; setTimeout(arguments.callee,20);}(); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-27 16:48:31 That seems dangerous to me. You're essentially just guessing that each file will be written in 20ms. If HDDs need to spin back up, or a file is huge, this will fail just like B_O_B_M's original case. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: fbuser on 2020-07-27 16:55:58 That seems dangerous to me. You're essentially just guessing that each file will be written in 20ms. If HDDs need to spin back up, or a file is huge, this will fail just like B_O_B_M's original case. No, it's not dangerous. You just need to make additional tests during the processing and return false return true, if the file, which needs to be processed is not ready. Additionally a guard should be implemented to avoid endless processing. Edit: Corrected and extended the answer. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2020-07-27 19:36:24 @All. Thanks for your replies. My best effort was to create an autoplaylist targeted at the destination for the converted files. I made a note of the file total and tested the playlist index of the autoplaylist and file count in the 'on_playlist_items_added(playlistIndex)' event. When I had all the files in the destination folder, I continued and embedded the album image in them all. Seems to work so far. Thanks for your valuable time spent in helping me on this. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-31 15:05:14 @MordredKLB , I've tinkered around a bit . Regretfully, it seems that it's impossible to make slow script dialog asynchronyous (without writing/using a new GUI stack): the problem is that GUI handling/processing is performed on the main thread, so if the main thread is stuck (e.g. in the infinite loop in JS), then no GUI messages can be processed making it impossible to interact with any dialogs (including slow script dialog). While I understand your problem, I just don't know what can be done without removing the slow script check. I will try to extend the time limit a bit for the script on fb2k startup (in case there's some async stuff that hogging up the CPU), but it's still won't be a universal solution and it might not help much in your case. [EDIT] Welp, no idea how to check that fb2k has loaded everything. Hence decided to make slow script time limit configurable (Advanced > SMP > Performance > Execution time limit). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-31 21:22:08 @MordredKLB , I've tinkered around a bit . Regretfully, it seems that it's impossible to make slow script dialog asynchronyous (without writing/using a new GUI stack): the problem is that GUI handling/processing is performed on the main thread, so if the main thread is stuck (e.g. in the infinite loop in JS), then no GUI messages can be processed making it impossible to interact with any dialogs (including slow script dialog). While I understand your problem, I just don't know what can be done without removing the slow script check. I will try to extend the time limit a bit for the script on fb2k startup (in case there's some async stuff that hogging up the CPU), but it's still won't be a universal solution and it might not help much in your case. [EDIT] Welp, no idea how to check that fb2k has loaded everything. Hence decided to make slow script time limit configurable (Advanced > SMP > Performance > Execution time limit). Thanks for investigating and I was afraid that might be the issue. In further thinking, I might play around with async loading, just to see if maybe that can help. It all depends on what's actually happening behind the scenes with FB freezes trying to read from the HDD. i.e. do the other threads completely get locked out while that's happening, or are they just processing very slowly. If it's the first (which seems likely) then there's nothing to be done, but if it's the second, it might make this issue harder to encounter. It's weird though that SMP can still display the dialog. Honestly this seems like a FB issue, and I'm wondering if we should report to @Peter . Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-31 21:45:14 It's weird though that SMP can still display the dialog. SMP can display a modal slow script dialog during JS execution, because this dialog is invoked during JS interruption callback (i.e. it actually stops JS execution, thus it no longer stalls the main thread). The dialog could not have been displayed if the main thread was stalled by smth not JS related (this not JS related stuff might slow-down JS execution enough to trigger the slow script though). If you have a debugger (e.g. visual studio), you may try to diagnose the issue by attaching to fb2k and breaking during the freeze. It will at least show the .dll on which fb2k is stuck. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-07-31 21:57:42 Well this is my confusion. Are you saying SMP executes the JS in the main thread then? In that case I would have thought that the interruption handler wouldn't have been able to work since it's also on the main thread, unless I'm misunderstanding how that even works. I might try the debugger trick, or maybe just wait and see if I'm the only one actually running into the issue. It's a pain in the ass to get conditions right to even occur naturally (although I haven't messed with HDD spin-down times yet...) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-07-31 22:14:35 Are you saying SMP executes the JS in the main thread then? Yep. Most of the JS stuff is executed on the main thread. A lot (most?) of GC is performed on worker threads though (memory deallocation is not cheap, so it gives a good performance boost). In that case I would have thought that the interruption handler wouldn't have been able to work since it's also on the main thread, unless I'm misunderstanding how that even works. I didn't look in the Spider Monkey internals too much, but it probably looks smth like this: Code: [Select] // SM internals// Everything here is executed on the main threadvoid JSMachineRunner(){ while (hasStuffToDo) { auto currentPart = GetNewPart(); ExecuteJSMaybe(currentPart); }}void ExecuteJSMaybe(JSPart part){ if (interruptRequested) { InvokeInterruptCallback(); } ExecuteJS(part);} I.e. in JS engine itself the JS code is not monolithic, but split in parts that are fed in a JS runner (even an infinite loop like while(true){}). Thus making the interruption (and slow script dialog) possible. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-08-01 05:32:06 Got it. Well, i'll give the async script loading a shot. Wrap every file in a await promise with setTimeout(() => {}, 1) and see if that improves the situation. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Mrakobes on 2020-08-01 16:43:58 problem 1: Artist Images (thumbs.js) help to configure the paths for displaying the covers in the "covers" folder, the problem is that sometimes I place this folder in the album, it is one level higher (in the case of a two-disc edition) - I just can't configure the second option. I want the code to look for the "covers" folder first in the lower directory, then, not finding it there, went up one level, and so on problem 2: last.fm similar artists + user charts + recent tracks similar unicode characters are not displayed correctly (bands in German, French) problem 3: last.fm I can not configure the folder for uploading photos from last.fm to the same directory as the artist problem 4: musicbrainz the discography is sorted by year in reverse order and I want to increase Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-09-24 21:26:00 I might try some tests with async/await wrapping includes. Wanted to follow up that loading scripts async made the issue go away. I haven't seen the slow-script warning popup in the last 2 months. My code for anyone who has this same problem (probably nobody else): Code: [Select] function loadAsyncFile(filePath) { return new Promise(resolve => { setTimeout(() => { include(filePath); resolve(); }, 1); })}const basePath = fb.ProfilePath + 'georgia\\';async function includeFiles(fileList) { for (let i = 0; i < fileList.length; i++) { await loadAsyncFile(basePath + fileList[i]); }}includeFiles([ 'js\\CaTRoX_QWR\\lodash.min.js', . . . // all other files]); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-09-25 21:06:51 @Mrakobes , regretfully my free time is very limited currently (even more than before, because of the new job I've landed). Because of that I won't be focusing on script development, but rather on component itself (I will steal some script fixes\improvements from @marc though :P) @MordredKLB , glad to hear that it's working out for you =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-09-25 23:16:54 Hi :) This is obviously not the best moment judging from your last post. I just wanted to remind you this one from about 6 months ago, so you can keep it in mind when the moment comes. Many thanks in advance ! @wcs13 , it might be possible to implement such logic in the script (ignoring low-res images that is), but I'm currently prioritizing component development over script improvement. In other words it won't be fixed anytime soon, sorry. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-09-26 03:40:42 Quick hack, complete\js\thumbs.js, line 492, replace the existing function with this.. Code: [Select]  this.update = () => { this.image = 0; this.files = []; this.images = []; let tmp = _getFiles(this.folder, this.exts, this.properties.sort.value == 1); tmp.forEach((item) => { let img = gdi.Image(item); if (img && img.Width >= 500 && img.Height >= 500) { this.files.push(item); this.images.push(img); } }); this.size(true); window.Repaint(); } Change the dimensions as required. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-09-26 11:27:18 ^Forget I posted that. It will lead to undesirable/buggy behaviour. It could be done properly but I'm far too lazy for that. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-10-25 11:18:01 fb.GetNowPlaying() method returns the actually playing (or paused) track, and returns a null value when the player is stopped, but it seems that foobar2000 stores a reference to the track even once it is stopped, because it is resumed when pressing the "play" button subsequently. Panel Stack Splitter also seems to access that reference when titleformat mode on start up is set to "Now playing". So, given my assumption is not wrong, is there a SMP method that returns that same reference? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-10-25 11:36:38 That's why callbacks like on_playback_stop exist. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-10-25 14:16:11 That's why callbacks like on_playback_stop exist. Yes, but this does not answer my question. or does it? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2020-10-25 16:48:55 That's why callbacks like on_playback_stop exist. Yes, but this does not answer my question. or does it? I believe Marc is saying that in the on_playback_stop you could record a reference to the track. From what I can tell, I think you're actually confusing having a reference to the last song played with the active playlist item. If I stop a song, and then press play, it isn't that foobar is remembering what the song is, it's just playing from the current position of the active playlist. When I play an entire playlist and then playback stops, when I hit play again, it doesn't play the last song, it plays the first song in the playlist. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-10-25 18:17:08 If I stop a song, and then press play, it isn't that foobar is remembering what the song is, it's just playing from the current position of the active playlist. But if I stop a song and then select another item in the active playlist, when I press play the playback does not start from the selected item, but from where the playback stopped. Furthermore, it does so even if I move the selected item above the previously playing song, so that its index is changed, which apparently means foobar is remembering the song and not the position. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-10-26 08:50:15 EDIT: Sorry, I posted in the wrong thread! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-10-26 19:10:13 It seems I have no idea what anyone is on about. I thought the original issue was something like this. Code: [Select] var g_metadb = fb.GetNowPlaying() // could be a valid handle or nullfunction on_playback_new_track(metadb) { g_metadb = metadb; // always a valid handle}function on_mouse_lbtn_up(x, y) { if (g_metadb) { //code here would run even if playback has stopped so long as g_metadb was valid at some point previously }} I would "fix" like this... Code: [Select] function on_playback_stop(reason) { g_metadb = null;} g_metadb would always be a valid handle when playing and null when not. Now it seems the issue has nothing to do with scripts/components at all and is simply not having main menu->"Playback/Playback follows cursor" enabled?? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-10-26 21:35:31 My issue arises from the need to make a SMP script consistent with that of a PSS panel where titleformatting mode on startup is set to "now playing". Indeed it looks as if PSS is keeping record of the last played track, but I was wondering if this is what's actually going on under the hood or if PSS is referencing some value provided by foobar2000. My question was not how to keep record of the last playing track, which is not a big deal, but whether this supposed foobar2000 internal reference exists and if I'm missing a SMP method the retrieves it. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Emerelle on 2020-10-27 17:19:42 Hi, thank you very much for this awesome panel! I updated almost all of my very outdated WSH panels and Im very happy. One question - and a request for coding help :/ I am using the sample script of the menu button. I would love to add an onHover image to the menu image though. Can someone give me pointers into the right direction? Here is the script I use: Code: [Select] 'use strict';window.DefinePanel('Menu Button', {author:'marc2003'});include(fb.ComponentPath + 'samples\\complete\\js\\lodash.min.js');include(fb.ComponentPath + 'samples\\complete\\js\\helpers.js');include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');let panel = new _panel(true);let buttons = new _buttons();buttons.buttons.menu = new _button(0, 0, 36, 36, {normal : 'misc\\foobar2000.png'}, (x, y, mask) => { _menu(0, 36); }, 'Menu');function on_focus(is_focused) { if (is_focused) { plman.SetActivePlaylistContext(); }}function on_colours_changed() { panel.colours_changed(); window.Repaint();}function on_mouse_lbtn_up(x, y, mask) { buttons.lbtn_up(x, y, mask);}function on_mouse_leave() { buttons.leave();}function on_mouse_move(x, y) { buttons.move(x, y);}function on_mouse_rbtn_up(x, y) { if (buttons.buttons.menu.trace(x, y)) { _help(0, 36); return true; } else { return panel.rbtn_up(x, y); }}function on_paint(gr) { panel.paint(gr); buttons.paint(gr);}function on_size() { panel.size();} Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-10-28 19:35:43 I am using the sample script of the menu button. I would love to add an onHover image to the menu image though. Can someone give me pointers into the right direction? From what I gather, you can add the hover image as a property of the fifth argument of the _button() function, which is an object. If you look at line 10, you will see the img_src argument which is Code: [Select] {normal : 'misc\\foobar2000.png'} Just add another property with key "hover" and value either an image (GdiBitmap), or if you place the image in the "samples\complete\images" directory, a string with the last part of the image path. For example Code: [Select] {normal : 'misc\\foobar2000.png', hover : 'buttons\\menu_hover.png'} The _button() function code where you can learn all this is in the "samples\complete\js\helpers.js" script. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Emerelle on 2020-10-29 05:22:37 Thank you so much, davideleo! It is hard for me since I am not a programmer at all; I will try out your suggestion today :) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: JOSHSKORN on 2020-10-30 18:06:15 Hi. I'm I've been racking my brain, trying to create a custom list of my library and I just can't seem to figure it out. Basically, I want to list all of my artists and then albums. See table example: List(Artist, Album, Genre, Total Album Length, Total Number of Tracks, Date, Front, Back, CD) The fields Front/Back/CD are to test the immediate folder for the contents of Front.jpg, Back. jpg and CD. jpg. Can this be accomplished using Spider Monkey Panel? If so, is there sample coding I can work off of? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2020-10-31 12:18:17 Hi. I'm I've been racking my brain, trying to create a custom list of my library and I just can't seem to figure it out. Basically, I want to list all of my artists and then albums. I'm very sympathetic to your issue because after some months of studying javascript I was still lost applying it to foobar2000 and the answer marc2003, alias @snotlicker , gave me to a similar question was enlightening and a turning point for me (I still have to thank him for this). You can read the exchange here (https://hydrogenaud.io/index.php?topic=110516.msg941771#msg941771). Since that was a jscript panel discussion, here is a spider monkey version of the code, which is also lodash-free. Code: [Select] fb.ShowPopupMessage(listByTag("artist").join("\n"));function listByTag(tag){ let tags = []; let items = fb.GetQueryItems(fb.GetLibraryItems(), tag + " PRESENT"); for (let i = 0; i < items.Count; i++) { let num = fb.TitleFormat("$meta_num(" + tag + ")").EvalWithMetadb(items[i]);        for (let j = 0; j < num; j++) {            tags.push(fb.TitleFormat("$meta(" + tag + "," + j + ")").EvalWithMetadb(items[i])); } } return [...new Set(tags)].sort();} Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Emerelle on 2020-11-01 10:07:08 I had been using one of the one-panel examples, the text reader script. It crashed my foobar ever so often that I had to take the panel out of my layout. I didnt add any modifications of the code at all, so I was wondering if there is a known issue with the loading time of this script? I get a "one script on this page is not responding" message when I add it to my layout up to the point foobar2000 will not come up anymore at all. Its a real shame since I store the contents of audiobooks in a info.txt file. Any hint very welcome! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2020-11-03 17:07:37 @TheQwertiest Regarding the callback on_script_unload() The docs say: Called when: - Panel script is reloaded via context menu > Reload. - Panel script is changed via panel menu > Configure. - fb2k is exiting normally. Not called when: - Script fails with error. - fb2k closed externally (e.g. killed with process manager). - fb2k fails with exception. Do the same restrictions apply as the jscript component that the callback is not guaranteed to be called during unloading.? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-11-03 19:53:59 @zeremy , AFAIK, JSP has mostly the same behaviour as SMP regarding on_script_unload. It's just not listed explicitly. @Emerelle , does it fail for every track? Or does it fail only on specific file? If the latler, please send me an example, so I can reproduce the problem. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-11-04 08:06:32 not guaranteed to be called during unloading.? I think that was inherited from WSH panel mod and I've never given it a moments thought. I guess I should test/update the docs. I'm pretty sure it's always called but the original dev was just being extra cautious. In addition to the SMP docs you quoted, it should also be called when removing/replacing a panel in layout editing mode. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Emerelle on 2020-11-04 12:11:03 @TheQwertiest It fails on load, when I start foobar. I get a notification that a script takes too long to load and if I want to stop it or wait for it to load. Sometimes even foobar does not load at all anymore and I have to kill the process. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Mrakobes on 2020-11-05 10:12:12 Recently (after updating the player), the script started to crash, this is observed on some audio. (https://i114.fastpic.ru/thumb/2020/1105/80/_137c398386c40388a1238df355d9cd80.jpeg) (https://i114.fastpic.ru/big/2020/1105/80/_137c398386c40388a1238df355d9cd80.png) I understand that the code was developed in collaboration with marc2k3, can here take the files https://github.com/marc2k3/foo_jscript_panel only problem is that samples are there in TXT no JS Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: VERDAE on 2020-11-05 17:26:15 Hey, I downloaded the SMP debug and now I'm getting this error whenever I try to open Foobar. What can I do to fix this? I'm also somewhat new to foobar so I apologize if this is a stupid question lol: Error: Spider Monkey Panel v1.3.2-beta+f0830b60 ({269F9404-C9AD-4BFA-957D-26628B44C199}) include failed: ActiveXObject_Constructor failed: Invalid CLSID: UIHacks File: JStheme_common.js Line: 863, Column: 26 Stack trace: oUIHacks@JStheme_common.js:863:26 @JStheme_common.js:1023:17 @<main>:1:1 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2020-11-05 21:13:09 not guaranteed to be called during unloading.? I think that was inherited from WSH panel mod and I've never given it a moments thought. I guess I should test/update the docs. I'm pretty sure it's always called but the original dev was just being extra cautious. In addition to the SMP docs you quoted, it should also be called when removing/replacing a panel in layout editing mode. @snotlicker I found that the culprit not letting me run the callback in a script was your helpers.js that was an include. It has the function Code: [Select] function on_script_unload() { _tt('');} in it and the second on_script_unload() in my script didn't get executed. Maybe some sanity checks are needed as to define the same function only once. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-11-05 21:31:43 The normal convention in javascript is that if a function with the same name is defined more than once, the last version always takes precedence. For example... Code: [Select] function message(name) { console.log("hello", name);}function message(name) { console.log("bye", name);}message("zeremy"); // always outputs "bye zeremy" But the include function built in to SMP breaks this convention so if the first definition is inside an include file, that will take precedence instead. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-11-18 16:07:17 Quick hack, complete\js\thumbs.js, line 492 ^Forget I posted that. It will lead to undesirable/buggy behaviour. It could be done properly but I'm far too lazy for that. Thanks for trying though :) I hope it can be done properly by TheQwertiest or you at some point, because low-res art tends to ruin the whole Thumbs experience. In my case I have a nice bio on the left half of the screen... and quite often I have a low-res art on the right half, even though I know that many hi-res pics exist for the same artist/album. Hi-res art should definitely be prioritized IMHO (when available). It's not about completely avoiding low-res, but rather about preferring hi-res when possible. Fingers crossed. :) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-11-19 09:16:39 This might work instead... Code: [Select]  this.update = () => { this.image = 0; this.files = []; this.images = []; _(_getFiles(this.folder, this.exts, false)) .map((item) => { var img = gdi.Image(item); return { path : item, image : img, area : img.Width * img.Height }; }) .orderBy((item) => { return item.area; }, 'desc') .forEach((item) => { this.files.push(item.path); this.images.push(item.image); }); this.size(true); window.Repaint(); } Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-11-19 19:44:12 This might work instead... Thanks, trying to make it work :) EDIT - doesn't seem to work. I have tried it on Beyoncé. It seemed like a good example, since her last.fm page has 5000+ pictures, some low-res, some hi-res. The modified Thumbs.js just appears to download the first n pictures in her page (in my case the first 10 pictures), regardless of their size. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2020-11-19 20:44:54 That code is simply for re-arranging files that are inside the folder. Don't like it? Don't use it. Do I really need to tell you that asking about thousands of images online is ****ing insane. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: wcs13 on 2020-11-20 01:06:51 I may have missed something, but I don't think I was rude at all in my message. So why are you ? :o Do I need to remind you what was kindly requested months ago in the first place ? @wcs13 , it might be possible to implement such logic in the script (ignoring low-res images that is), but I'm currently prioritizing component development over script improvement. In other words it won't be fixed anytime soon, sorry. You just posted a bit of code, with no indications of what it's supposed to do. I'm not a dev. So of course I didn't examine the code, because I thought you were answering to what was requested. Now you say that your code was only for re-arranging images (from hi-res to low-res in foobar I guess), which has little to do with what was requested (ignoring, not re-arranging). Now don't get me wrong : I'm grateful for your bit of code and I'm grateful for you wanting to help. It's of course better than nothing, but it's hardly a solution, because if Thumbs.js downloaded a majority of low-res images in the first place, then sorting them will not be very useful, unless we're only interested in the first or second image. BTW, did I ever ask about parsing thousands of images online ? No ! :o I'm not that stupid. Ignoring low-res images can be much simpler. I assume you know lots of ways to do it. Here's one : • Check image 1. If enough-res, save it, or else ignore it. Go to the next image. • Repeat until you have n enough-res saved images. • In some cases, if after parsing all the images (some artists have very few images) we don't have n saved images, then save some low-res images too until we have n saved images. If we are reasonable with the enough-res resolution (e.g. 360.000 pixels min, that's 600x600), we won't need to ignore lots of images. So for n saved images, I guess we may need to parse 1.5n images, maybe 2n images, but hardly more. I guess that's what @TheQwertiest suggested that he'd do when he'd have some time. If somebody is willing to do it, I'm sure I won't be the only one to be grateful. If not, then I'll just keep waiting. There's nothing else I can do. BTW here's how my 32" 1440p display looks with a low-res image (see attached file). Like I said, it ruins the whole experience a bit. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2020-12-10 19:44:43 Is it possible to rename the main menu entries? (I was expecting it would be available on the preferences panel) Why? Because adding those menu commands to standard foobar buttons give the menu name as tool-tip texts. Renaming the menu entries would give a clue of what they do without having to use text buttons. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cooldude on 2020-12-12 21:02:43 I've been trying to find a convenient way to view, select and automatically cycle through all the images which are in the same folder as a song, and also a subdirectory below. The "Artist Images"/"thumbs.js" script which is included is nearly perfect. But currently, it only shows images from the same directory as the music file - using this: Code: [Select] $directory_path(%path%)
How do I set it up so that it also shows images from a directory below the file (for example, if there's a folder filled with covers)?
In addition, is it possible to also have it show embedded album art? Currently it can't.

So in summary, I'd like it to show the images in the same folder, the images in any folder which is directly below, and embedded images.

The last and smallest thing that would be nice to have, is to somehow change this background color (currently black):

(https://i.imgur.com/T46BJ6F.png)
The included setting doesn't change it.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: regor on 2020-12-13 21:03:09
Probably not exactly what you needed, since I'm using other script. But sure you can take the path part to suit your needs.

Code: [Select]
window.DefinePanel("LoadImageAsync", { author: "XXX" });let sel = ""let path = ""if (fb.IsPlaying) {    sel = fb.GetNowPlaying();    path = fb.TitleFormat("$directory_path(%path%)").EvalWithMetadb(sel);}// Get a list of jpg files from a foldervar pathart = "" if (utils.FileTest(path + '\\art', "e")) pathart = '\\art\\';else if (utils.FileTest(path + '\\artwork', "e")) pathart = '\\artwork\\';else if (utils.FileTest(path + '\\_artwork', "e")) pathart = '\\_artwork\\';const g_image_list = utils.Glob(path + pathart + '*.jpg');let ww = 0, wh = 0;let g_img = null;let g_valid_tid = 0;// Trigger every 5 seconds.let g_timer = setInterval(function () { load_random_image_async();}, 5000);load_random_image_async();function on_playback_new_track() { let g_timer = setTimeout(function () { window.Reload(); }, 1000);}function on_playback_starting() { let g_timer = setTimeout(function () { window.Reload(); }, 1000);}function load_random_image_async() { // Load a random image from the list let path = g_image_list[Math.floor(Math.random() * g_image_list.length)]; // on_load_image_done will be triggered when the image has been loaded g_valid_tid = gdi.LoadImageAsync(window.ID, path);}function on_size() { ww = window.Width; wh = window.Height;}function on_paint(gr) { if (!g_img) { return; } let scale_w = ww / g_img.Width; let scale_h = wh / g_img.Height; let scale = Math.min(scale_w, scale_h); let pos_x = 0, pos_y = 0; if (scale_w < scale_h) { pos_y = (wh - g_img.Height * scale) / 2; } else if (scale_w > scale_h) { pos_x = (ww - g_img.Width * scale) / 2; } gr.DrawImage(g_img, pos_x, pos_y, g_img.Width * scale, g_img.Height * scale, 0, 0, g_img.Width, g_img.Height);}// After loading image is done in the background, this callback will be invokedfunction on_load_image_done(tid, image, image_path) { if (g_valid_tid === tid) { g_img = image; window.Repaint(); }} "Pathart" is the subfolder part you want. Ex: ACDC/Black in black/Artwork/front.jpg ACDC/Black in black/Artwork/... ACDC/Black in black/track1 .... ACDC/Black in black/cover.jpg I only have 3 possible artwork sub-folder names, so that's the 3 "if sentences" part. Then const g_image_list = utils.Glob(path + pathart + '*.jpg') just merges the file path (track folder) with the subfolder path and takes all jpg files. It should work with any other extension, but beware I have no idea if js displays png or other image files right. I just note you can put whatever you want on that list. So the first part of this script should work for you in your script in some way. It just displays 1 image at a time and cycle it. About adding the embedded artwork, I have a "cover.jpg" file present on the base folder, so that's what I would check. Adding that file to the image list too. If you talk about the cover within the track, then you can check "GetAlbumArtAsync.js" on samples folder. EDIT: After re-reading.. btw if it's just a matter of config editing and you can put whatever tittle-formatting you want then:$directory_path(%path%) --> $directory_path(%path%)\artwork That should do. Or your desired subfolder name. (Note, anyway, that would restrict the images to just the subfolder). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cooldude on 2020-12-14 23:03:03 EDIT: After re-reading.. btw if it's just a matter of config editing and you can put whatever tittle-formatting you want then:$directory_path(%path%) --> $directory_path(%path%)\artwork That should do. Or your desired subfolder name. (Note, anyway, that would restrict the images to just the subfolder). Thanks. However, I can't find any "GetAlbumArtAsync.js" file anywhere, and probably wouldn't know what to do with it. The way I can select particular images with the "thumbs.js" script is quite slick and practical, and something similar would be a must if I'm going to bother with this. But it seems it may not be possible to simultaneously view images from folders, subfolders and embedded images while using it. I also don't mind using other scripts if there's ones which would work for all this. It's just that without being able to view all three sources simultaneously (images in folders, subfolders, and embedded), most of the album art in my different collections would end up missing. There's an older WSH artwork script which might work and I want to try, hopefully someone can reupload it: https://hydrogenaud.io/index.php?topic=77883.msg991453#msg991453 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: dwmartin0906 on 2020-12-20 01:03:50 Hi. I have a strange issue using the on_mouse_mbtn_up function. When my script is in an embedded panel, I have to double click to get the desired result. A single click is ignored. But when the same script is in a foo_flowin pop-up panel, it works just fine. I also use on_mouse_lbtn_up and it works fine either way. Does any one have an idea what might be causing this? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2020-12-25 16:19:07 Ignoring low-res images can be much simpler. I assume you know lots of ways to do it. Here's one : Check image 1. If enough-res, save it, or else ignore it. Go to the next image. Repeat until you have n enough-res saved images. That's actually the problem. To get image dimensions you need to download it. So, if there are only low-res images, you'll have to download all those images first. Is it possible to rename the main menu entries? (I was expecting it would be available on the preferences panel) I have plans to totally rework main menu buttons feature (and make it possible to generate buttons dynamically), but I don't think it will be done any time soon. Hi. I have a strange issue using the on_mouse_mbtn_up function. What do you mean by "embedded panel"? Also can you attach an example script that has such problem? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: dwmartin0906 on 2020-12-26 02:56:36 Thank you for responding. I used the term "embedded panel" to refer to a normal Foobar panel as defined with splitters, as opposed to pop-up panels created with foo_flowin. And I found the problem. Another component was set up to use the middle mouse button, even though I had never used it. I redefined the keys used by that component and on_mouse_mbtn_up now works as expected with a single click. I've just started learning Spider Monkey scripting and am amazed at the power and flexibility it offers. Thank you very much for this amazing component and the excellent documentation you provide. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2020-12-26 17:59:46 9483] Is it possible to rename the main menu entries? (I was expecting it would be available on the preferences panel) I have plans to totally rework main menu buttons feature (and make it possible to generate buttons dynamically), but I don't think it will be done any time soon. [/quote] That would be much appreciated. Also, would it be possible to add a Find(handle) → {number} function with configurable order (inverted too)? Or one which outputs all coincidences? I'm working on a remove duplicates" function (more advanced than 'same raw path'), while maintaining playlist order by duplicating handles and working on sorted lists on parallel to the original one (A). For 17K tracks that means 1.5 seconds (A). 327 seconds working without cloned sorted list. And 369 ms if I don't care about original order at all. The problem I got for (A) is that remove(handle) removes all coincidences (but I one to maintain one!), so I use Find(handle) to then remove by ID at the original unsorted list. But... it obviously outputs just one match, instead of all. And it always search from the start of the list, so the removed position is not configurable. I'm currently doing this within some loops and other code (for tags): Code: [Select]  let handleAidx =[]; let idx = handle_list.Find(handleA); //Needed. Or it would remove all instances of the same handle! let idxcache = idx; while (idxcache != -1) { handle_list.RemoveById(idxcache); idxcache = handle_list.Find(handleA); } handle_list.Insert(idx,handleA); //It was last copy. Revert once to first place. break; With oriented search it would convert to: Code: [Select]  let idxA = handle_list.Find(handleA); let idxB = handle_list.Find(handleA,-1); //Inverse while (idxA != idxB) { handle_list.RemoveById(idxB); idxB = handle_list.Find(handleA,-1); } break; Or find array result: Code: [Select]  let findArray= handle_list.Find(handleA); let i = findArray.length; while (i--) { handle_list.RemoveById(findArray[i]); } break; Which would be so much better and faster. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: sndsAU on 2021-01-08 02:25:07 Hi, I am using the Spider Monkey panel and the included sample file "js smooth browser" for a cover art browser. My question is, is there a way to actually cache the artwork to local disk? My music is stored on a NAS and the artwork is embedded in the flac files. There is a setting that can be selected in the popup menu "Enable Disk Image Cache" but this seems broken/has no effect. Everytime foobar is restarted, the panel has to reread the art from remote files. Thanks. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-01-14 08:34:41 Utils.Version returns the version of SMP, but I was wondering if there a way to get the version of foobar currently running? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2021-01-14 09:56:43 Utils.Version returns the version of SMP, but I was wondering if there a way to get the version of foobar currently running? Code: [Select] fb.TitleFormat("%_foobar2000_version%").Eval(true); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-01-14 16:22:43 Brilliant. Should have known there'd be a title_format field. Thank man! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-15 10:37:07 How do I load a playlist by path? LoadPlaylist() doesn't accept any argument according to the documentation Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-15 10:53:14 plman.AddLocations. It expects an existing playlistIndex as one of the args so you might want to create a new one with plman.CreatePlaylist first. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-15 11:15:13 plman.AddLocations. It expects an existing playlistIndex as one of the args so you might want to create a new one with plman.CreatePlaylist first. Yep, got it working. The idea is to have a playlist manager with {names/paths} and load playlists on foobar only on demand (instead of cluttering the playlist tab with all playlist loaded at the same time). So the name (and thus new ID needed) will be already given by the object. Thanks! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-01-15 17:14:07 @TheQwertiest FYI, the latest nightly causes foobar to crash on startup. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-01-15 17:16:52 @TheQwertiest FYI, the latest nightly causes foobar to crash on startup. Are you using DUI? (https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/129) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-01-15 20:08:47 @TheQwertiest FYI, the latest nightly causes foobar to crash on startup. Are you using DUI? (https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/129) Yup. I'll give the new nightly a look. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-01-16 15:53:37 Using nightly build (v1.3.2-beta+9a1b2b36). Exploring the changed features. panel properties/ configuration (one with three tabs). Can you please make this re-sizeable. Also on the properties tab (same as old version), can you please increase the width of the horizontal splitter as it's very difficult to grab with the mouse and move. On a more general note, I hope all your great ideas for v2 have been included into the single project git project. Looking forward to the next official version. Thanks for your efforts. They are very much appreciated. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-01-16 16:43:46 Can you please make this re-sizeable. I'd like to, but, TBH, my UI programming skills are close to non-existent >_< But I will try... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-16 17:37:05 Speaking about the properties panel (I'm using the stable release btw), could the keys be sorted following natural number order? As is, it's currently broken for anything over 9. 10 appears after 1. Or should I force it adding zeros? (most times I don't know how many properties will be created with my buttons framework so it's not trivial) Btw, are you open to any other suggestion for the panel? - I'm thinking about predefined values: if you set true to a property, the panel already shows a dropdown with true/false. Allowed values could be set with the current set function as a third argument (not breaking current scripts). -Could a property panel be created according to an ID? Right now I just add properties sequentially to the current SMP panel whenever I merge/add buttons... I assign different IDs and prefixes to the properties so every button has it's own set. But obviously that add a ton of variables to the properties panel. Creating panels on demand with an ID would solve that, I would simply assign every panel to its own button. Then overriding the menu on right click to show button properties instead of panel properties. As you see, I'm currently doing it with prefixes + numbers at script loading, so at least the sorting part would be a lifesaver. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-01-16 18:19:49 Speaking about the properties panel (I'm using the stable release btw), could the keys be sorted following natural number order? Not sure, I need to check if there's any built-in sorting function that allows to do that, since I don't want to drag a big chunk of code in component just for that. For now you can just append three zeroes, I mean I doubt that there'll be more than 1k buttons :D - I'm thinking about predefined values: if you set true to a property, the panel already shows a dropdown with true/false. Allowed values could be set with the current set function as a third argument (not breaking current scripts). I was entertaining this idea, actually. This is one of the big features that I want to work on: - additional display mode for Properties dialog: properties are displayed as a tree view, where . character is used as a separator. - support for arrays (yet to figure how it will work though). - ability to set property type explicitly (in dialog and via JS). - support for enum values (the feature that you are requesting). - ability to manipulate properties as a json (where objects are generated the same way as the tree view). Not sure when I'll come around to implementing all that though. -Could a property panel be created according to an ID? Right now I just add properties sequentially to the current SMP panel whenever I merge/add buttons... I assign different IDs and prefixes to the properties so every button has it's own set. But obviously that add a ton of variables to the properties panel. Creating panels on demand with an ID would solve that, I would simply assign every panel to its own button. Then overriding the menu on right click to show button properties instead of panel properties. As you see, I'm currently doing it with prefixes + numbers at script loading, so at least the sorting part would be a lifesaver. The panels you are talking about are virtual panels, but there is no such concept in SMP right now and I don't think I want to introduce it and there several reasons for that: - This is quite a big feature. The proper concept introduction will require quite a lot of new API (and component code to support it). - It's use-case is quite niche. In 99,999% cases buttons don't need any additional properties and usually work just as a dumb callback-invoker. So, while idea itself is pretty cool, I just don't have any spare capacity to work on it (being the sole maintainer of this project and all that)... However, I do think you'll be able to work around your problems with the Properties rework, that I've mention above (without having to resort to implementing virtual panels in SMP). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-01-16 18:37:34 I just don't have any spare capacity to work on it To give you some idea on the workload: just a small overview of all the currently planned features for next releases: https://github.com/TheQwertiest/foo_spider_monkey_panel/projects/1#column-3416309 And that's not counting all other projects that I want to work on... >_< Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-01-18 02:05:55 And that's not counting all other projects that I want to work on... >_< The pain is real. It's why I seem to never succeed in finishing anything :D Thanks for all the amazing work on SMP though! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-01-18 09:11:55 @Qwertiest Not wishing to add to your workload too much... any chance of changing the file name sent to an external editor. At the moment it is smpxxxx.tmp. To help get the most out of MS Code for example, it would be good if the file name used was smpxxxx.js. ps Thanks for the easier-to-grip properties splitter Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-01-18 09:38:12 To give you some idea on the workload: just a small overview of all the currently planned features for next releases: https://github.com/TheQwertiest/foo_spider_monkey_panel/projects/1#column-3416309 Delighted to see these ❤ (https://lh3.googleusercontent.com/W5eF1c9v54jxQTOrMVZXIdzV4aS4y-FpNvWOQKunIxKC9Tz-tmpcrs75W_R28eIojMkcCjEVAoLGyYGNDD1GIuMj_EKSoxljbJ0WeFuCFqZzotoasPdkJ46tKqBOPRruKcP1b0rlDHZ_UMErRRuqJTKD45HDmyyLZfL_0uDEDSgAn0VuWXR4DBW-JbyxlvIrfTKeloDXJaOc3Hhf_YLSGwiQf8zfsg6h0eyYxDhtn6pCwsS-SnF-sVGhS4byBe_H-jFD714ykZTAiIKaFnCVYCDHZXtjN4v4NF-hiuywghaBxWU25G0C1CTCA4jLkt_51G-U2faZkZE0H0FNOchzCILV2ELx9sItX2RtBweOdoLnUWkAUgfmswP4LG2-cqe0cO_e13ZfRVg5q2Ha6gXODXQkftiah4nzcC0RaLNy1SkPdkTbIyAXUWjYLK24a3iqgYMDntyi2vKwLU1q8XYNloD-R19dUCbcOCVVijlIZ8LUo6hU5EpgLOh4YcOt7A2wfljSvmvt3bwvHFFsn3FfJUyjSTuPsSxXJIcX1SmlO26InEMvg0noI9M2xKB8Puk1SDYL-3fXznXtmC_3YeKpW1UrWt58YTKJTs3_kv8lJEo-CPC1QHKBR1YsLioG1tGZXdV2RwHVfdVTVOT5IRkB-8g79vrO0KrpDs9Hx3im3nHDxnOADsc2xMzlnKiK=w366-h347-no?authuser=0) Keep it up, this component makes foobar2000 so much fun! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-18 10:41:42 Not sure, I need to check if there's any built-in sorting function that allows to do that, since I don't want to drag a big chunk of code in component just for that. For now you can just append three zeroes, I mean I doubt that there'll be more than 1k buttons :D Yep, did that and works great. Most things have <30 options, and as you said I don't plan to have more than 10 buttons on the same bar. Quote - additional display mode for Properties dialog: properties are displayed as a tree view, where . character is used as a separator. - support for arrays (yet to figure how it will work though). - ability to set property type explicitly (in dialog and via JS). - support for enum values (the feature that you are requesting). - ability to manipulate properties as a json (where objects are generated the same way as the tree view). That would be great! I support arrays and objects separating keys/values by commas and then converting it to arrays/objects with my own helper hahahaha not pretty but works. I needed it to allow setting arbitrary tags on filters (remapping X tags to be treated as 'genre'). Or pairs {tag: value}. Obviously the downside is that you have to manually follow the convention needed for that property and warn about it on the description (one "solution" is use the value for that: PUT HERE AN OBJECT {...}). For simplicity I just use x,value,y,value... but I see no reason to allow "{}" or "[]" notation. Btw, I manipulate properties as objects. I simply create one with default properties (the main function), then I add new properties on buttons if required. Use [...old, ...new] and have my own set of functions to set, get all values at once. Since I use prefixes and unique IDs, I can pass the object to functions and load the associated properties by merging the default keys with the ID. That works good enough for me, and I even use properties to set tooltips dynamically for every button. Prefixes can be set to name different categories within the properties. Also using [...old, ...new], you can simply create 4 different properties objects on the js file (if that makes easier the readability or you need conditional settings) and then merging them. Not a tree like view but works. About that, the only thing I could not make to work are paths. Property values seem to be converted to strings when using the "get..."), so paths with "/" get broken. I was expecting to be able to use raw on output and then change "/" to "//" before converting the path to a string, but no way. Also that string implicit conversion gave me some headaches, since numbers were sometimes treated as strings until I found I had to explicitly add Number() when getting properties (and tags too! -like date-) Quote The panels you are talking about are virtual panels, but there is no such concept in SMP right now and I don't think I want to introduce it and there several reasons for that: - This is quite a big feature. The proper concept introduction will require quite a lot of new API (and component code to support it). - It's use-case is quite niche. In 99,999% cases buttons don't need any additional properties and usually work just as a dumb callback-invoker. Well that's exactly the use-case for all the things I have developed for playlist creation hahaha But it's working using my framework, so it's not a needed thing at all. Got it right with the padding and creating unique IDs. I also managed to show the IDs within the tooltips, so it's pretty easy to know which button is associated to which ID. That's good enough for me and once I share it on github, could be used by anyone as a workaround. Oh, and other thing I noticed these days. Just a question. Why the getMeta... way is slower than ussing TF? Let's say you have 30k tracks and I need to get all the values of genre, mood, style, etc. and then loop through them to check some things. I have noticed it's faster to use evalwithmetadbs(), setting a TF expression like "tagX | tagY ..." and then splitting things on multidimensional arrays using "|" per tag, and ", " per value than looping through files and getting tags... that was weird. I mean... the method to get tags is slower than the method expected to be the slowest one. What's the use of the getMeta... then? Am I missing something? And could you confirm this? Quote Thanks! Well the html rendering part is done outside foobar with a browser, so it's just using standard js code. I'm not sure if it could be integrated in any way within foobar as a html popup though (?) On github, you told me IE is used for html rendering, so I could try that path once I install it. I don't use fancy things, just standard js, SVG rendering and jquery as a library. It would be awesome: I could do things like showing tracks from the library matching the node selected, playlists by node and "radius", etc. I still have to check the iso subsong bug, I will update the issue on github as soon as I can. Thanks for this great component and all your work! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-01-18 11:31:00 @Qwertiest Not wishing to add to your workload too much... any chance of changing the file name sent to an external editor. At the moment it is smpxxxx.tmp. To help get the most out of MS Code for example, it would be good if the file name used was smpxxxx.js. Sure =) About that, the only thing I could not make to work are paths. Property values seem to be converted to strings when using the "get..."), so paths with "/" get broken. I was expecting to be able to use raw on output and then change "/" to "//" before converting the path to a string, but no way. Also that string implicit conversion gave me some headaches, since numbers were sometimes treated as strings until I found I had to explicitly add Number() when getting properties (and tags too! -like date-) Not sure I understand your problem with paths, could you elaborate, plz? Regarding strings and types - this is the only way I can find out the property type, i.e. I can't convert string to int myself, since it might've been intended to be a string by user, but just happened to contain numbers inside. Oh, and other thing I noticed these days. Just a question. Why the getMeta... way is slower than ussing TF? Let's say you have 30k tracks and I need to get all the values of genre, mood, style, etc. and then loop through them to check some things. I have noticed it's faster to use evalwithmetadbs(), setting a TF expression like "tagX | tagY ..." and then splitting things on multidimensional arrays using "|" per tag, and ", " per value than looping through files and getting tags... that was weird. I mean... the method to get tags is slower than the method expected to be the slowest one. What's the use of the getMeta... then? Am I missing something? What do you mean by getmeta? And could you confirm this? https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/utils.html#.ShowHtmlDialog @davideleo , no ETA though :P (as usual) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-18 16:10:48 What's the use of the getMeta... then? Am I missing something? The point of using GetFileInfo() is that you can access all tags within a file without knowing what they are. Using title formatting, you have to know in advance what tags you want to access. Load up the samples\properties sample. It doesn't know or care about your tags but displays them all regardless. If that script was based on title formatting, you'd have to tell it about each and every tag your files might contain. edit: some sections of that properties sample are based on title formatting but the main meta and tech info sections use GetFileInfo and loop through the available fields without knowing the names. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-18 21:59:06 Quote Not sure I understand your problem with paths, could you elaborate, plz? Regarding strings and types - this is the only way I can find out the property type, i.e. I can't convert string to int myself, since it might've been intended to be a string by user, but just happened to contain numbers inside. Let's say I create a property. window.GetProperty(blabla, 'C:\path\gbqaws'); For sure, that path it's wrong if you use it as is within js. You know it, I know it. Ok. But what about users? window.GetProperty(blabla, 'PUT HERE YOUR PATH'); Then the user just copy/paste paths from explorer and... 99.99% programs within windows give you paths with single "\" when copying them. Maybe that's easily solved with other method (I'm totally novice on js) but as far as I know the only way to manage that usage is using String.raw'whatever' . But that workaround does nothing in this case since the getProperty value has been already converted to string where escapes have been processed. So... window.GetProperty(blabla, 'PUT HERE YOUR PATH').replace('\','\\'); for sure doesn't work. neither String.raw'${window.GetProperty(blabla, 'PUT HERE YOUR PATH')}'.replace('\','\\');
nor
String.raw'${window.GetProperty(blabla, String.raw'C:\path\gbqaws')}'.replace('\','\\'); As far as I tested, you are forced to put double \ on the panel (?) because the returned value has been already converted to string. Similar behavior can be found with other escapes. Quote What do you mean by getmeta? This Code: [Select] function getTagsValues(handle, tagsArray, bMerged = false) { if (!isArrayStrings (tagsArray)) {return null;} if (!handle) {return null;} const sel_info = sel.GetFileInfo(); const tagArray_length = tagsArray.length; let outputArray = []; let i = 0; while (i < tagArray_length) { let tagValues = []; const tagIdx = sel_info.MetaFind(tagsArray[i]); const tagNumber = (tagIdx != -1) ? sel_info.MetaValueCount(tagIdx) : 0; if (tagNumber != 0) { let j = 0; while (j < tagNumber) { tagValues[j] = sel_info.MetaValue(tagIdx,j); j++; } } outputArray.push(tagValues); i++; } if (bMerged) {outputArray = outputArray.flat();} return outputArray;}; Is slower than this; Code: [Select] ]function getTagsValuesV3(handle, tagsArray, bMerged = false) { if (!isArrayStrings (tagsArray)) {return null;} if (!handle) {return null;} const tagArray_length = tagsArray.length; let outputArray = []; let i = 0; let tagString = ""; const outputArray_length = handle.Count; while (i < tagArray_length) { if (bMerged) {tagString += i == 0 ? "[%" + tagsArray[i] + "%]" : "[, " + "%" + tagsArray[i] + "%]";} // We have all values separated by comma else {tagString += i == 0 ? "[%" + tagsArray[i] + "%]" : "| " + "[%" + tagsArray[i] + "%]";} // We have tag values separated by comma and different tags by | i++; } let tfo = fb.TitleFormat(tagString); outputArray = tfo.EvalWithMetadbs(handle); if (bMerged) { // Just an array of values per track: n x 1 for (let i = 0; i < outputArray_length; i++) { outputArray[i] = outputArray[i].split(', ') } } else { // Array of values tag and per track; n x tagNumber let tfo = fb.TitleFormat(tagString); outputArray = tfo.EvalWithMetadbs(handle); for (let i = 0; i < outputArray_length; i++) { outputArray[i] = outputArray[i].split('| '); for (let j = 0; j < tagArray_length; j++) { outputArray[i][j] = outputArray[i][j].split(', '); } } } return outputArray;} Try it iterating on 30k tracks. I didn't understand how a TF approach is faster than using the methods to get tags. I mean... take a look at how many things I have to do to get usable output with TF... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-18 22:02:51 What's the use of the getMeta... then? Am I missing something? The point of using GetFileInfo() is that you can access all tags within a file without knowing what they are. Using title formatting, you have to know in advance what tags you want to access. Load up the samples\properties sample. It doesn't know or care about your tags but displays them all regardless. If that script was based on title formatting, you'd have to tell it about each and every tag your files might contain. edit: some sections of that properties sample are based on title formatting but the main meta and tech info sections use GetFileInfo and loop through the available fields without knowing the names. Ok that makes sense now... all my use-cases use already known tags names to compare things. So then those methods are only useful when iterating all tags. At least performance wise. I was slowing my scripts using the first approach without needing. Quote https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/utils.html#.ShowHtmlDialog Well If I understand the w3s web... looks bad, Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-18 22:25:42 For sure, that path it's wrong if you use it as is within js. You know it, I know it. Ok. But what about users? This is how the language works and there is nothing you can do about it. You have to do the same thing in C++ too. https://github.com/marc2k3/foo_jscript_panel/blob/c2cf47859536c1bfffc956cf3996ae5e9df7d70d/src/Helpers/Component.h#L10 If you're intending to share your scripts then you should be building menus/buttons that use utils.InputBox or the Properties dialog for entering strings. Editing scripts directly is obviously very error prone and is highly discouraged. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-18 23:12:34 For sure, that path it's wrong if you use it as is within js. You know it, I know it. Ok. But what about users? This is how the language works and there is nothing you can do about it. You have to do the same thing in C++ too. https://github.com/marc2k3/foo_jscript_panel/blob/c2cf47859536c1bfffc956cf3996ae5e9df7d70d/src/Helpers/Component.h#L10 If you're intending to share your scripts then you should be building menus/buttons that use utils.InputBox or the Properties dialog for entering strings. Editing scripts directly is obviously very error prone and is highly discouraged. That's what I already do. That's the point, I don't expect users to know \ should be doubled. It's also pretty inconvenient. I mean, the UI panel is exposed to the user... so I expect usage according to the user mentality (copy/paste). Using panels solves nothing if they put paths with single \ there, I was not talking about editing scripts directly. That's why string.raw exists, for arbitrary user input. But if nothing can be done about it, then I will just warn about it. EDIT: window.GetProperty(description, defaultval, function) wouldn't that solve the problem with types? Instead of Number(window.GetProperty(description, defaultval)) just window.GetProperty(description, defaultval, function(value) {return Number(value); }) Instead of strings processed just window.GetProperty(description, defaultval, function(value) {return string.raw'${value}'.replace('/','//'; })
function should be applied as first step when loading the user value, not later.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-01-18 23:25:55
You don't have to double the \ when using the Properties window. It really is that simple.

As an example, load up samples\thumbs. Do not use the Custom folder menu option that I've nicely added. Instead, hold down Shift+Winkey and right click to open the Properties (I always hide easy access).

Now edit the value for 2K3.THUMBS.CUSTOM.FOLDER.TF to any folder that contains images using single slashes and click OK. Do the images display? I should hope so...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: regor on 2021-01-18 23:32:26
You don't have to double the \ when using the Properties window. It really is that simple.
I'm lost... and how do you convert that string to something usable within your code then?
let path = window.GetProperty(blabla);

becomes an unusable string (?) and replace('\','\\'); wiill not work.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-01-18 23:39:41
I don't do anything and at this point, I'm out. :/
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: regor on 2021-01-19 00:04:48
Quote
Now edit the value for 2K3.THUMBS.CUSTOM.FOLDER.TF to any folder that contains images using single slashes and click OK. Do the images display? I should hope so...
Quote
Now edit the value for 2K3.THUMBS.CUSTOM.FOLDER.TF to any folder that contains images using single slashes and click OK. Do the images display? I should hope so...
Nope. Strings with single \ definitely don't work on the panel for me, that's why I reported it... because I have tested it. With your samples, I got this on console...

c:\Users\xxx\AppData\Roaming\foobar2000\scripts\SMP\samples\js-smooth\images\default.png (panel)
->
c:UsersxxxAppDataRoamingfoobar2000scriptsSMPsamplesjs-smoothimagesdefault.png (console)

If you assure the properties should work that way, I will check on a new foobar profile since there is definitely something wrong here.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-01-19 02:05:39
I should have made it clear that the script expects a path to a folder - not a filename.

Check the attachment to see my previous post illustrated.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2021-01-19 04:39:44
If you assure the properties should work that way, I will check on a new foobar profile since there is definitely something wrong here.
Yeah, I'm not sure what you're doing. As marc showed, it works just fine. I also tested this out just to make sure. If you're doing SetProperty in a script you have to escape the slashes, but you certainly don't when editing in the properties panel, because again, those are already strings.

A simple console.log(window.GetProperty('FOLDER_PATH')) will demonstrate that it's correct (once you've defined a property called FOLDER_PATH). Are you doing anything to those strings after calling GetProperty to retrieve them?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-01-19 10:55:30
I feel that you are talking past each other =)
So, I'll try to sum up all the things that @snotlicker said.

@regor , as it was mentioned above, in quite a few programming languages (and even in RegExp and windows command line) \ character is used as an escape character or to form a control character. For example, \n is a control character for a new line, \" - escape the quote character.
Values that can be seen in property dialog have all the escape chars and control chars parsed.

So, in JS (and SMP) it will work like this:
Code: [Select]
window.SetProperty("escape_1", "\"");console.log(window.GetProperty("escape_1"));  // Logged and displayed in Property dialog as "window.SetProperty("escape_2", "\\");console.log(window.GetProperty("escape_2"));  // Logged and displayed as \window.SetProperty("path_1", "path\\to\\file.ext");console.log(window.GetProperty("path_1")); // Logged and displayed as path\to\file.extwindow.SetProperty("path_2", "path/to/file.ext");console.log(window.GetProperty("path_2")); // Logged and displayed as path/to/file.extwindow.SetProperty("control_1", "line_1\nline_2");console.log(window.GetProperty("control_1")); // Logged as:// line_1// line_2// displayed as:// line_1line_2

Thus, path strings in JS code should be either like this path/to/file.ext or like this path\\to\\file.ext .
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Black_Over_Bills_Mothers on 2021-01-19 12:19:33
Hi
I'm trying to get an indication if the single track selected is an individual flac file or part of a multi-track flac file. Any ideas?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-01-19 17:21:29
Hi
I'm trying to get an indication if the single track selected is an individual flac file or part of a multi-track flac file. Any ideas?

Check if the path ends with .cue or use title formatting for embedded cuesheets %__cue_embedded% equals yes
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-01-19 17:44:49
Check if the path ends with .cue or use title formatting for embedded cuesheets %__cue_embedded% equals yes
If cue is external (i.e. not embedded), you may also try checking FbMetadbHandle.SubSong, it seems to be above zero only when it's a multi-track file.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-01-19 17:53:47
I always thought SubSong begain with zero for the first track which is why I didn't mention it. My mistake!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-01-19 18:24:23
I always thought SubSong begain with zero for the first track which is why I didn't mention it. My mistake!
So did I =)
Just happened to have a cue file in my library to actually verify it >_<
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Black_Over_Bills_Mothers on 2021-01-19 19:15:10
Well done and thanks.
Most of my examples are a single flac file without a .cue companion. And low-and-behold the .SubSong method yields 1 upwards for each track. It is always 0 for non multi-track flacs.

Great.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Black_Over_Bills_Mothers on 2021-01-20 10:18:36
Just found out that if you use the internal editor to export a script and the name has spaces in it then the external editor (MS Code in my case) doesn't like it. Eg export as "prep new music" then use the external editior, MS Code opens two text files (prep and new) and one js file (music.js). Not sure if it's worth a code change but it's worth noting.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-01-20 14:02:04
Just found out that if you use the internal editor to export a script and the name has spaces in it then the external editor (MS Code in my case) doesn't like it. Eg export as "prep new music" then use the external editior, MS Code opens two text files (prep and new) and one js file (music.js). Not sure if it's worth a code change but it's worth noting.
That's a bug =)
Will be fixed.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: LeVvE on 2021-01-20 18:03:58
I've tried looking through the documentation but I'm not getting any wiser so I thought I'd ask here.

I want to make a button that switches between shuffle track and default playback that works like how the play/pause button in the sample "playback buttons", anyone have any suggestions on how to make it work?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2021-01-20 20:13:46
I've tried looking through the documentation but I'm not getting any wiser so I thought I'd ask here.

I want to make a button that switches between shuffle track and default playback that works like how the play/pause button in the sample "playback buttons", anyone have any suggestions on how to make it work?

Code: [Select]
			if (plman.PlaybackOrder === 4){				fb.RunMainMenuCommand("Playback/Order/Default");			} else {				fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)");			}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: regor on 2021-01-20 21:37:05
I feel that you are talking past each other =)
So, I'll try to sum up all the things that @snotlicker said.

@regor , as it was mentioned above, in quite a few programming languages (and even in RegExp and windows command line) \ character is used as an escape character or to form a control character. For example, \n is a control character for a new line, \" - escape the quote character.
Values that can be seen in property dialog have all the escape chars and control chars parsed.

So, in JS (and SMP) it will work like this:
Code: [Select]
window.SetProperty("escape_1", "\"");console.log(window.GetProperty("escape_1"));  // Logged and displayed in Property dialog as "window.SetProperty("escape_2", "\\");console.log(window.GetProperty("escape_2"));  // Logged and displayed as \window.SetProperty("path_1", "path\\to\\file.ext");console.log(window.GetProperty("path_1")); // Logged and displayed as path\to\file.extwindow.SetProperty("path_2", "path/to/file.ext");console.log(window.GetProperty("path_2")); // Logged and displayed as path/to/file.extwindow.SetProperty("control_1", "line_1\nline_2");console.log(window.GetProperty("control_1")); // Logged as:// line_1// line_2// displayed as:// line_1line_2

Thus, path strings in JS code should be either like this path/to/file.ext or like this path\\to\\file.ext .
Was a bug on my installation. New foobar profile worked right, I reinstalled everything and now works as expected. Have no idea what was going on.. since same lines of code behaved differently on different profiles.

Btw, I have one more doubt. I'm trying to create a playlist manager, like the autoplaylist list on samples but for standard playlists.
Right now I got it like this: There is a monitored folder, the UI loads all files within that folder (playlists), I can open them and they are loaded within foobar, update the file (i.e. save foobar playlist to binded file), rebind playlist and rename (renaming playlist on manager, renames the file itself and the playlist on foobar). All that is working. I only have a problem, I can delete the files using this function from helpers .
Code: [Select]
let app = new ActiveXObject('Shell.Application');function _recycleFile(file) {	if (_isFile(file)) {		app.NameSpace(10).MoveHere(file);	}}
But restoring the file becomes a problem. I can not find a way to move files from the bin to the original folder.  I use the Move method with this, something like this
Code: [Select]
let fso = new ActiveXObject('Scripting.FileSystemObject');let recyclePath = "c:\\$RECYCLE.BIN\\" + app.NameSpace(10) + "\\" + file.FILENAME;let restorePath = file.PATH;fso.MoveFile(recyclePath , restorePath ); But files are never moved from the bin. I have tried with that recyclePath which does indeed work on explorer, but not using the move function. So as far as I understand, the path should be right since it works on explorer (?) "c:\$RECYCLE.BIN\" points to the physical folder, and  "c:\$RECYCLE.BIN\" + app.NameSpace(10) to the virtual one containing all files from any HDD Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: LeVvE on 2021-01-21 14:33:00 I've tried looking through the documentation but I'm not getting any wiser so I thought I'd ask here. I want to make a button that switches between shuffle track and default playback that works like how the play/pause button in the sample "playback buttons", anyone have any suggestions on how to make it work? Code: [Select]  if (plman.PlaybackOrder === 4){ fb.RunMainMenuCommand("Playback/Order/Default"); } else { fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)"); } That code worked to switch, thanks a lot. I have to ask for more help though, sadly. I want to swap icon based on which order is active, how do I add that? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-01-21 18:38:57 That code worked to switch, thanks a lot. I have to ask for more help though, sadly. I want to swap icon based on which order is active, how do I add that? Well, you can use the plman.PlaybackOrder (https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/plman.html#.PlaybackOrder) property to write a conditional statement for that, too, much in the same way as above. To keep it simple, if you are using actual images: Code: [Select] function on_paint(gr){ let img_path; if (plman.PlaybackOrder === 4){ img_path = //path to the default icon image } else { img_path = //path to the shuffle icon image } let img = gdi.Image(img_path) gr.GdiDrawBitmap(img.CreateRawBitmap(), dstX, dstY, dstW, dstH, srcX, srcY, srcW, srcH)} If you are using font icon characters the principle is the same. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: LeVvE on 2021-01-21 18:55:40 That code worked to switch, thanks a lot. I have to ask for more help though, sadly. I want to swap icon based on which order is active, how do I add that? Well, you can use the plman.PlaybackOrder (https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/plman.html#.PlaybackOrder) property to write a conditional statement for that, too, much in the same way as above. To keep it simple, if you are using actual images: Code: [Select] function on_paint(gr){ let img_path; if (plman.PlaybackOrder === 4){ img_path = //path to the default icon image } else { img_path = //path to the shuffle icon image } let img = gdi.Image(img_path) gr.GdiDrawBitmap(img.CreateRawBitmap(), dstX, dstY, dstW, dstH, srcX, srcY, srcW, srcH)} If you are using font icon characters the principle is the same. I think I'm too dumb for this, the current thing I use is this: Code: [Select] buttons.buttons.shuffle = new _button(2, 2, 32, 32, {normal : 'buttons\\Menu.png'}, (x, y) => { if (plman.PlaybackOrder === 4){ fb.RunMainMenuCommand("Playback/Order/Default"); } else { fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)"); } }, 'Shuffle'); Maybe I should just look for another skin that has this function and see how they did it because I can't figure this out. When I add the function I get image is null. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-01-21 20:07:04 I think I'm too dumb for this, the current thing I use is this: Code: [Select] buttons.buttons.shuffle = new _button(2, 2, 32, 32, {normal : 'buttons\\Menu.png'}, (x, y) => { if (plman.PlaybackOrder === 4){ fb.RunMainMenuCommand("Playback/Order/Default"); } else { fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)"); } }, 'Shuffle'); Maybe I should just look for another skin that has this function and see how they did it because I can't figure this out. When I add the function I get image is null. I see, you're editing marc's script! I thought you were writing your own code. That makes it a little more complicated because you need to look at the code of at least three different scripts to understand where and how to edit (playback buttons, helpers and panel I think). I don't use it and I'm not familiar with it, but in that line of code you posted, the button image is likely passed by the fith argument of the _button() function, which is an object: Code: [Select] {normal : 'buttons\\Menu.png'} So first of all you need to have the required image files in the buttons folder and than you could try replacing "menu" with a variable and assign that variable the appropriate value with the conditional statement I suggested in the previous post. You could write the conditional statement in the on_playback_order_changed() callback, for example. But really, I would need to have a better look at the scripts before suggesting anything. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: LeVvE on 2021-01-21 20:32:51 I think I'm too dumb for this, the current thing I use is this: Code: [Select] buttons.buttons.shuffle = new _button(2, 2, 32, 32, {normal : 'buttons\\Menu.png'}, (x, y) => { if (plman.PlaybackOrder === 4){ fb.RunMainMenuCommand("Playback/Order/Default"); } else { fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)"); } }, 'Shuffle'); Maybe I should just look for another skin that has this function and see how they did it because I can't figure this out. When I add the function I get image is null. I see, you're editing marc's script! I thought you were writing your own code. That makes it a little more complicated because you need to look at the code of at least three different scripts to understand where and how to edit (playback buttons, helpers and panel I think). I don't use it and I'm not familiar with it, but in that line of code you posted, the button image is likely passed by the fith argument of the _button() function, which is an object: Code: [Select] {normal : 'buttons\\Menu.png'} So first of all you need to have the required image files in the buttons folder and than you could try replacing "menu" with a variable and assign that variable the appropriate value with the conditional statement I suggested in the previous post. You could write the conditional statement in the on_playback_order_changed() callback, for example. But really, I would need to have a better look at the scripts before suggesting anything. So you recommend I start from scratch instead? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-01-21 20:43:23 So you recommend I start from scratch instead? I encourage anyone to write their own rather than hacking other people's scripts, unless they are fairly simple and straightforward standalone scripts. But good coders usually don't have standalone scripts, but more complex systems which are hard to edit without breaking something. Nevertheless, meanwhile I had a look at the scripts and something easy you could try is editing the line of code you posted as follows: Code: [Select] buttons.buttons.shuffle = new _button(2, 2, 32, 32, {normal : plman.PlaybackOrder === 4 ? 'buttons\\deafult.png' : 'buttons\\shuffle.png'}, (x, y) => { if (plman.PlaybackOrder === 4){ fb.RunMainMenuCommand("Playback/Order/Default"); } else { fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)"); } }, 'Shuffle'); Than add the following: Code: [Select] function on_playback_order_changed(){ buttons.update(); window.Repaint();} Of course this works if you have a "shuffle.png" and "default.png" file in the buttons folder. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-01-21 21:06:12 P.S. While we are at it, you can use the ternary operator ('?' and ':') for the conditional statement of the command as well: Code: [Select] buttons.buttons.shuffle = new _button(2, 2, 32, 32, {normal : plman.PlaybackOrder === 4 ? 'buttons\\deafult.png' : 'buttons\\shuffle.png'}, (x, y) => plman.PlaybackOrder === 4 ? fb.RunMainMenuCommand("Playback/Order/Default") : fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)"), 'shuffle'); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: LeVvE on 2021-01-22 00:37:57 P.S. While we are at it, you can use the ternary operator ('?' and ':') for the conditional statement of the command as well: Code: [Select] buttons.buttons.shuffle = new _button(2, 2, 32, 32, {normal : plman.PlaybackOrder === 4 ? 'buttons\\deafult.png' : 'buttons\\shuffle.png'}, (x, y) => plman.PlaybackOrder === 4 ? fb.RunMainMenuCommand("Playback/Order/Default") : fb.RunMainMenuCommand("Playback/Order/Shuffle (tracks)"), 'shuffle'); Works just the way I want it, thanks for your help :) This is how I made it look, top right corner, greyed out when not enabled: (https://i.imgur.com/z0yNpwn.png) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-01-24 11:43:49 @Qwertiest I've added some info. on issue 'ActiveXObject error when dealing with exotic filename encodings #54' on github. Hope this helped. If you need further info. please let me know. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: fbuser on 2021-01-24 12:04:34 Check if the path ends with .cue or use title formatting for embedded cuesheets %__cue_embedded% equals yes If cue is external (i.e. not embedded), you may also try checking FbMetadbHandle.SubSong, it seems to be above zero only when it's a multi-track file. Not necessarily. If you are using mtags with one file for each track, the subsong index is always 1. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-24 19:31:23 How do you save a playlist to a path? I found nothing about that on the documentation only SavePlaylist() and using a main menu command I can not add the path. Quote But restoring the file becomes a problem. I can not find a way to move files from the bin to the original folder. I use the Move method with this, something like this Any help there would be appreciated too. Thanks! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-26 12:19:54 How do you save a playlist to a path? I found nothing about that on the documentation only SavePlaylist() and using a main menu command I can not add the path. marc2k3 just aded that functionality btw. Quote But restoring the file becomes a problem. I can not find a way to move files from the bin to the original folder. I use the Move method with this, something like this Any help there would be appreciated too. Thanks! Well just found the problem is the (physical) name gets changed by the SO after sending a file to the Recycle Bin, so "a.txt" is changed to "$K4354A.txt" or things like that, while the explorer displays the original (virtual) name. I have now to list all files on the bin and identify the one I deleted, will report if that works for restoring purposes.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: regor on 2021-01-26 13:35:06
Also, is there some method to create a simple yes/no popupBox without using HTML?

popupBox(window_id, prompt, okString, cancelString)  -> return true/false

Obviously InputBox() could be used along try/catch to emulate that functionality but it looks weird (since the window expects a text input).

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-01-26 14:25:12
Well just found the problem is the (physical) name gets changed by the SO after sending a file to the Recycle Bin, so "a.txt" is changed to "$K4354A.txt" or things like that, while the explorer displays the original (virtual) name. I have now to list all files on the bin and identify the one I deleted, will report if that works for restoring purposes. You can get original filename by using the following code: Code: [Select] let dir = app.NameSpace(10);let items = dir.Items();// Regretfully, dir.Items() is not enumerable, so it must be traversed manuallyfor (let i = 0; i < items.Count; ++i) { console.log(items.Item(i).Name); // original name console.log(items.Item(i).Path); // full path in recycle bin} How do you save a playlist to a path? I found nothing about that on the documentation only SavePlaylist() and using a main menu command I can not add the path. Not sure I want to add this method, but I will put it on the maybe list in case I change my mind (it does happen =)). Also, is there some method to create a simple yes/no popupBox without using HTML? Not currently, but I'll see if it can be done. @Qwertiest I've added some info. on issue 'ActiveXObject error when dealing with exotic filename encodings #54' on github. Hope this helped. If you need further info. please let me know. Thanks, I'll take a look. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-26 14:40:11 Simple popups are already possible and have been in my samples for years. Code: [Select] let WshShell = new ActiveXObject('WScript.Shell');let popup = { ok : 0, yes_no : 4, yes : 6, no : 7, stop : 16, question : 32, info : 64};let prompt = ...let caption = ...if (WshShell.Popup(prompt, 0, caption, popup.question + popup.yes_no) == popup.yes) { //do something} edit: see here for other button combos I've not included https://www.devguru.com/content/technologies/wsh/wshshell-popup.html Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-26 15:04:20 Yep I did the same and finally got it working. Thanks :) For reference, if anyone needs to do the same (it's just an improvement to marc's helpers): Code: [Select] const fso = new ActiveXObject('Scripting.FileSystemObject');const app = new ActiveXObject('Shell.Application');function _isFile(file) { return _.isString(file) ? fso.FileExists(file) : false;}function _isFolder(folder) { return _.isString(folder) ? fso.FolderExists(folder) : false;}function _createFolder(folder) { if (!_isFolder(folder)) { try { fso.CreateFolder(folder); } catch (e) { return false; } return _isFolder(folder); } return false;}function _deleteFile(file) { if (_isFile(file)) { try { fso.DeleteFile(file); } catch (e) { return false; } return !(_isFile(file)); } return false;}function _renameFile(file, newFilePath) { if (!_isFile(newFilePath) { if (_isFile(file)) { try { fso.MoveFile(file, newFilePath); } catch (e) { return false; } return _isFile(newFilePath); } return false; } return false;}function _recycleFile(file) { if (_isFile(file)) { try { app.NameSpace(10).MoveHere(file); } catch (e) { return false; } return !(_isFile(file)); } return false;}function _restoreFile(file) { if (!_isFile(file)) { const arr = utils.FileTest(file, "split"); const OriginalFileName = arr[1]; const items = app.NameSpace(10).Items(); const numItems = items.Count; for (let i = 0; i < numItems; i++) { if (items.Item(i).Name == OriginalFileName) { _renameFile(items.Item(i).Path, file); break; } } let bFound = _isFile(file); if (!bFound){console.log('_restoreFile(): Can not restore file, "' + OriginalFileName + '" was not found at the bin.');} return bFound; } else { console.log('_restoreFile(): Can not restore file to "' + file + '" since there is already another file at the same path.'); return false; }} Btw utils.FileTest() seems to have a bug. Code: [Select] let arr = utils.FileTest("D:\\Somedir\\Somefile.txt", "split")// arr[1] <= "Somefile.txt" extension included (?) Not sure if that's intended, but the documentation says otherwise: Code: [Select] let arr = utils.FileTest("D:\\Somedir\\Somefile.txt", "split");// arr[0] <= "D:\\Somedir\\" (always includes backslash at the end)// arr[1] <= "Somefile"// arr[2] <= ".txt" PD: For reference, if that behaviour get's fixed, then the scripts at top should reflect that change too. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-26 15:06:43 Simple popups are already possible and have been in my samples for years. Code: [Select] let WshShell = new ActiveXObject('WScript.Shell');let popup = { ok : 0, yes_no : 4, yes : 6, no : 7, stop : 16, question : 32, info : 64};let prompt = ...let caption = ...if (WshShell.Popup(prompt, 0, caption, popup.question + popup.yes_no) == popup.yes) { //do something} edit: see here for other button combos I've not included https://www.devguru.com/content/technologies/wsh/wshshell-popup.html Oh that... yes. That's why I asked, I was sure I have been seeing them somewhere! I would prefer to not use ActiveXobjects but it's good enough. Thanks! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-26 15:20:01 I can see the bug with utils.FileTest here... https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/150e49cdc072762b1a6b6a90d7e5be1158bbba50/foo_spider_monkey_panel/js_objects/utils.cpp#L298 It should use stem(), not filename(). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-27 09:58:33 Finally got all working on the playlist manager, and managed to get playlist size (#tracks) by using m3u directives and/or counting lines if they are missing. But I have a limitation, I can easily read/write m3u, m3u8 files and create schemes for them but I have no way to read fpl files. If I want to know the number of tracks from a fpl playlist, is there any other way other than loading the playlist within foobar, and using plman.PlaylistItemCount(index)t? I mean, is there a way to bypass playlist loading into the UI? fpl -> Handle list EDIT: since addLocations(playlistIndex, paths, selectopt) is async and there is no other method to load a playlist, the mentioned method doesn't work since PlaylistItemCount returns 0 because the playlist loading is not done yet when called. And having in mind all this involves playlist being temporarily shown on the UI, I think I should avoid using promises for creating/count/deleting temp playlists. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-27 10:34:18 No. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-27 14:13:19 Another bug: I have folder with these files: Code: [Select] c:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\Lucia Emotivas.fplc:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\Post-Britpop.m3u8c:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\World.m3u Code: [Select] utils.Glob(folderPath + '*.m3u').concat(utils.Glob(folderPath + '*.m3u8')).concat(utils.Glob(folderPath + '*.fpl')).concat(utils.Glob(folderPath + '*.pls'));On console, win 7, there are 4 files:[15:11:36] ["C:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\Post-Britpop.m3u8", "C:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\World.m3u", "C:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\Post-Britpop.m3u8", "C:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\Lucia Emotivas.fpl"] Same script on win 10: 3 files Code: [Select] [15:11:36] ["C:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\World.m3u", "C:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\Post-Britpop.m3u8", "C:\Users\XXX\AppData\Roaming\foobar2000\playlist_manager\Lucia Emotivas.fpl"] utils.Glob(folderPath + '*.m3u') matches '*.m3u8' too on win 7. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-27 14:45:16 Seems like its not a component bug but a windows API issue. But you can just use *.* and filter by extension yourself. Code: [Select] const allowed = ["m3u", "m3u8", "pls", "fpl"];let files = utils.Glob("z:\\*.*").filter((item) => { return allowed.includes(item.split('.').pop().toLowerCase());}); Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-01-27 15:45:29 Yep, I did something similar. @TheQwertiest Also check PathWildcardMatch(), since being a bug with the API it probably has the same behavior. If you need testing on win 7 just let me know, I use both. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MachineHead on 2021-01-27 18:50:55 Not sure if this has been brought up, but can very old WSH scripts be updated to work in SMP? This one in particular has probably never been updated from its original release there. (https://www.deviantart.com/br3tt/art/WSH-CoverFlow-290788027) Happened to stumble across it in an old config I had tucked away and thought I'd ask. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) - Knops Post by: 2tec on 2021-01-30 20:10:44 There's some knobs, some with javascript, hosted on this site ~ https://codepen.io/tag/knob/ implementing one's a little beyond me at this point, perhaps someone with more know how will find this useful Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MojoBass on 2021-01-31 05:48:23 Not sure if this has been brought up, but can very old WSH scripts be updated to work in SMP? This one in particular has probably never been updated from its original release there. (https://www.deviantart.com/br3tt/art/WSH-CoverFlow-290788027) Happened to stumble across it in an old config I had tucked away and thought I'd ask. Guess your linked WSH Coverflow is the basis for this (https://hydrogenaud.io/index.php?topic=110516.msg985835#msg985835) script running well in my config within JScript Panel 2.5.2 from marc2k3/ @snotlicker . Not really maintained by anybody, but there is still some helping hand from @snotlicker or @MordredKLB (Thanks!!) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-01-31 08:05:49 No one ever reads anything do they? https://theqwertiest.github.io/foo_spider_monkey_panel/docs/guides/jsp_to_smp_migration_guide/ Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MachineHead on 2021-01-31 19:03:26 *snip* Thanks for that. Works great. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-01 12:20:24 Code: [Select]  // Doesn't work arr.push({ 'REPLAYGAIN_ALBUM_GAIN' : '', 'REPLAYGAIN_ALBUM_PEAK' : '', 'REPLAYGAIN_TRACK_GAIN' : '', 'REPLAYGAIN_TRACK_PEAK' : '' }); sel_items.UpdateFileInfoFromJSON(JSON.stringify(arr)); // Works fb.RunContextCommandWithMetadb("ReplayGain/Remove ReplayGain information from files", sel_items, 8); Why UpdateFileInfoFromJSON is not able to clear ReplayGain tags? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-02-01 13:43:33 Can you edit replaygain values from the Metadata tab of the Properties dialog? There's your answer. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-01 16:50:42 So it's a foobar's limit. Yep masstagger has the same limit too. Had no idea it was so hardcoded, I thought it was just a soft limit to force users to use the proper UI. Makes no sense to me to block it on scripts/components too, but thanks! Will use the component menu. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-02-01 17:51:09 I'm pretty sure the SDK exposes other ways to manipulate RG values, just not the method used for updating normal tags. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Emerelle on 2021-02-02 08:37:34 I am using the script Album Art. I wonder if it is possible to set it to autorefresh on folder change? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-02 13:14:02 Simple popups are already possible and have been in my samples for years. I knew I've seen it somewhere! it's being too long since I've last coded anything non-trivial on SMP/JSP... I can see the bug with utils.FileTest here... https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/150e49cdc072762b1a6b6a90d7e5be1158bbba50/foo_spider_monkey_panel/js_objects/utils.cpp#L298 It should use stem(), not filename(). Thanks! utils.Glob(folderPath + '*.m3u') matches '*.m3u8' too on win 7. Yep, as Marc have said, it's a WinAPI bug (*sigh*): https://stackoverflow.com/a/44933735 That said, I'll see if I can reimplement this method to avoid this. Also check PathWildcardMatch() PathWildcardMatch (reportedly) does not have such a bug. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-03 15:38:26 One more question, maybe I'm missing something. Is there some way to have a "on_mouse_lbtn_dblclk(x, y)" and "on_mouse_lbtn_up(x, y)" at the same time for the same item? For ex: I have this UI, if I click lbtn then it shows a contextual menu. If I try to double click, I want it to load the playlist. As workaround, I have used a modifier key and it's good enough for me. But wanted to know anyway. EDIT: nevermind. I see I can use setTimeout() to delay the contextual menu and then it works. But double clicking will not cancel its the execution of the delayed function so... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-03 16:09:18 One more question, maybe I'm missing something. Is there some way to have a "on_mouse_lbtn_dblclk(x, y)" and "on_mouse_lbtn_up(x, y)" at the same time for the same item? For ex: I have this UI, if I click lbtn then it shows a contextual menu. If I try to double click, I want it to load the playlist. As workaround, I have used a modifier key and it's good enough for me. But wanted to know anyway. EDIT: nevermind. I see I can use setTimeout() to delay the contextual menu and then it works. But double clicking will not cancel its the execution of the delayed function so... That's just the way SMP/JSP/WSH work: double click produces the following events: Code: [Select] on_mouse_lbtn_downon_mouse_lbtn_upon_mouse_lbtn_dblclkon_mouse_lbtn_up So yeah, you have to take in account all the possible scenarios (if you want to handle both click and double click) . For example, you can store is_mouse_down and was_double_clicked states (e.g. https://github.com/TheQwertiest/CaTRoX_QWR/blob/61eecfa4159e3714d58f53ae942d5f1861e83fb2/theme/Scripts/Control_List.js#L230). [EDIT]: See the post below. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-03 16:25:27 Oh, I think I've misunderstood what you are trying to achieve. Your scenario is impossible to implement properly (i.e. without delays), since to know if the event is click or a double-click one must know the future =) That's why 99% of the time single-click invokes an action that is a part of a double-click action or at the very least does not contradict a double-click action. E.g. click - Select, dblclick - Execute the selected item; click - Select the whole string, dblclick - Select only one word from the string. IMO, you should rework your scenario and remove the context menu from the click action. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-03 17:23:26 Oh, I think I've misunderstood what you are trying to achieve. Your scenario is impossible to implement properly (i.e. without delays), since to know if the event is click or a double-click one must know the future =) That's why 99% of the time single-click invokes an action that is a part of a double-click action or at the very least does not contradict a double-click action. E.g. click - Select, dblclick - Execute the selected item; click - Select the whole string, dblclick - Select only one word from the string. IMO, you should rework your scenario and remove the context menu from the click action. Yep, was that. I have managed to do it though, with delays... Code: [Select]  this.lbtn_up = (x, y) => { // on_mouse_lbtn_up(x, y) ... if (!this.bDoubleclick) { // it's not a second lbtn click this.timeOut = this.delayedEdit(x,y, undefined, this.index); } else {this.bDoubleclick = false;} ... } this.lbtn_dblclk = (x, y) => { // Called by on_mouse_lbtn_dblclk(x, y) clearTimeout(this.timeOut); this.timeOut = null; this.bDoubleclick = true; ...doyourthing } this.edit = (x, y, menuIdx = null, forcedIndex = null) => { // use index from on_mouse_move(x, y), so you have to forceIndex from first call ...doyourthing } this.delayedEdit = delayFn(this.edit, 100); this.timeOut = null; this.bDoubleclick = false; on helpers Code: [Select] const delayFn = (func, ms) => { return (...args) => {return setTimeout(func.bind(this, ...args), ms);}} I have to pass the index to this.edit() because the mouse may move after clicking once and select another thing different to the original one which fired the contextual menu, but it works flawless now. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-04 22:35:29 Just downloaded the nightly build (@22:30 GMT). On restart of foobar I see the following a stack of many popup windows all with the same message: WinAPI error: IIDFromString failed with error (0x80070057): The parameter is incorrect. This also appears in the console. Unable to use foobar at this point. I have resorted to a previous nightly build and all is okay. I have lost WilB's library tree and biography panel contents, properties but I've managed to recover 90%. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-04 22:49:37 More questions. I got a panel like this, with drag n drop enabled. I have 2 use cases: - "Moving" tracks to a playlist item at the panel. Quote (Spider Monkey Panel specific) All mouse callbacks are suppressed during drag operation (including on_mouse_lbtn_up, but excluding on_mouse_mbtn_up and on_mouse_rbtn_up). But according to the documentation, I can not track the mouse movement within the panel (?) to check the index the mouse is over. So judging the dragndrop sample I should use on_drag_enter() , etc. with the same functions I already have at on_mouse_move(x, y) to check the index I'm over, and then link that index to the handles I drop. Right? -- "Moving" files to the panel (which is linked to a folder). I'm talking about the physical playlist file here. As far as I have seen, all the drag n drop functions expect at some point handles... and moving a file within foobar treats it automatically as a track, or a collection of tracks if it's a playlist. Is there some way to get the actual playlist file path (and not its tracks) when using drag n drop? i.e. make no assumption about what the files are, and just get their path. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2021-02-05 09:49:32 This script works in JSP , but not in SMP. Code: [Select] var xml = '<person><name>John Doe</name></person>';var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");xmlDoc.async="false";xmlDoc.loadXML(xml);var data = xmlDoc.getElementsByTagName('name');console.log(data[0].childNodes[0].nodeValue); Any ideas why ?? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-05 12:19:28 Just downloaded the nightly build (@22:30 GMT). On restart of foobar I see the following a stack of many popup windows all with the same message: WinAPI error: IIDFromString failed with error (0x80070057): The parameter is incorrect. This also appears in the console. Unable to use foobar at this point. I have resorted to a previous nightly build and all is okay. I have lost WilB's library tree and biography panel contents, properties but I've managed to recover 90%. Darn, I'm sorry for these problems. I'll fix it ASAP. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-05 13:10:21 @Black_Over_Bills_Mothers , could you paste the version of the working nightly? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-05 13:50:44 This the latest working version: Spider Monkey Panel v1.3.2-beta+5e1f7be3 by TheQwertiest Based on JScript Panel by marc2003 Based on WSH Panel Mod by T.P. Wang Build: 00:22:51, Feb 4 2021 Columns UI SDK Version: 6.5 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-05 14:41:47 <snip> Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-05 19:15:47 - "Moving" tracks to a playlist item at the panel. Quote (Spider Monkey Panel specific) All mouse callbacks are suppressed during drag operation (including on_mouse_lbtn_up, but excluding on_mouse_mbtn_up and on_mouse_rbtn_up). But according to the documentation, I can not track the mouse movement within the panel (?) to check the index the mouse is over. So judging the dragndrop sample I should use on_drag_enter() , etc. with the same functions I already have at on_mouse_move(x, y) to check the index I'm over, and then link that index to the handles I drop. Right? Yes, on_mouse_move is replaced with on_drag_over. -- "Moving" files to the panel (which is linked to a folder). I'm talking about the physical playlist file here. As far as I have seen, all the drag n drop functions expect at some point handles... and moving a file within foobar treats it automatically as a track, or a collection of tracks if it's a playlist. Is there some way to get the actual playlist file path (and not its tracks) when using drag n drop? i.e. make no assumption about what the files are, and just get their path. Noted, but I don't think this will be implemented in this release. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-05 20:14:03 @Qwertiest Not sure if this helps you but I've tried the nightly build: Spider Monkey Panel v1.3.2-beta+dd28ed6b by TheQwertiest Based on JScript Panel by marc2003 Based on WSH Panel Mod by T.P. Wang Build: 19:12:53, Feb 5 2021 Columns UI SDK Version: 6.5 And all working fine. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-05 20:20:01 This the latest working version: Spider Monkey Panel v1.3.2-beta+5e1f7be3 by TheQwertiest Based on JScript Panel by marc2003 Based on WSH Panel Mod by T.P. Wang Build: 00:22:51, Feb 4 2021 Columns UI SDK Version: 6.5 Should be fixed in the latest nightly. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-05 20:25:51 Thank you so much. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-06 14:00:33 This script works in JSP , but not in SMP. Any ideas why ?? Because of the subpar subscript handling =) Almost every interaction with COM objects (aka ActiveXObject in JS interface) has to be implemented in SMP manually... This is not a problem for JSP and WSH, since their implementation is actually based on COM objects. Should be fixed in nightly. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-06 19:21:26 - "Moving" tracks to a playlist item at the panel. Quote (Spider Monkey Panel specific) All mouse callbacks are suppressed during drag operation (including on_mouse_lbtn_up, but excluding on_mouse_mbtn_up and on_mouse_rbtn_up). But according to the documentation, I can not track the mouse movement within the panel (?) to check the index the mouse is over. So judging the dragndrop sample I should use on_drag_enter() , etc. with the same functions I already have at on_mouse_move(x, y) to check the index I'm over, and then link that index to the handles I drop. Right? Yes, on_mouse_move is replaced with on_drag_over. Well I looked at it again and maybe I miss something but that part can not be done too. The drag n drop sample just redirects the action to another playlist by Id. I can drop tracks to a playlist already loaded since I can assign its Id to the action (b), but I can not simply get the handle list of the drag n drop action without sending it to a playlist (a). a) My workflow is: drop -> handle list -> get paths of tracks -> save paths into .m3u8 file b) For a playlist already loaded: drop -> playlist -> autosave paths to linked .m3u8 playlist file Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-06 19:40:07 The drag n drop sample just redirects the action to another playlist by Id. Yes, it does (unless you block it by changing Effect to DROPEFFECT_NONE). can not simply get the handle list of the drag n drop action without sending it to a playlist Yes, you can't. As I've said in the previous post, your feature request is acknowledged and will be implemented sometime in the future (i.e. it's a totally valid use-case and not a niche feature). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-06 23:16:53 @The Qwertiest Using nightly build: Spider Monkey Panel v1.3.2-beta+01dd8c13 by TheQwertiest Based on JScript Panel by marc2003 Based on WSH Panel Mod by T.P. Wang Build: 22:04:47, Feb 6 2021 Columns UI SDK Version: 6.5 I get popup windows and WilB's Biography script script (v1.1.3) crashes. The error given is: WinAPI error: GetTypeInfo failed with error (0x80070005): Access is denied. File: <main> Line: 29, Column: 42 Stack trace: htmlParse@<main>:29:42 Lfm_top_albums/this.Analyse@<main>:1158:5 Lfm_top_albums/this.on_state_change@<main>:1148:154 Panel/this.get_multi/getTopAlb<@<main>:888:83 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-07 08:36:31 @TheQwertiest Just updated to foobar2000 1.6.4 (from early beta) and all working with SMP latest nightly. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-07 09:01:11 @TheQwertyiest Oops! Spoke too soon. Script still crashing but a lot less often. Previously it was always at startup. Now it can be several minutes usage - but always after a band/artist change and always the Biography script. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-02-07 09:08:43 It happens when parsing the html for a webpage it doesn't already have a cached file for. I've not looked at that bio script but I can reproduce with this... Code: [Select] var doc = new ActiveXObject('htmlfile');function _getElementsByTagName(value, tag) { doc.open(); var div = doc.createElement('div'); div.innerHTML = value; var data = div.getElementsByTagName(tag); doc.close(); return data;}var html = "<html><div class=\"text\"><p>blah</p></div></html>";var divs = _getElementsByTagName(html, "div");console.log(divs.length) // 1, OK While the above function seems to create an array as expected, any attempt to access any element fails... Code: [Select] if (divs[0].className == "text") console.log(divs[0].innerText);//orconsole.log(typeof divs[0]); Code: [Select] WinAPI error: GetTypeInfo failed with error (0x80070005): Access is denied. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: kode54 on 2021-02-07 09:17:43 This component supports ActiveX? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-02-07 09:31:10 Yep. Currently there is no other way to manage files/folders, access the internet etc. I guess it could all be implemented via SDK helpers/WinAPI but it would be even more effort than mangling ActiveX support in. Obviously it's all way over my head. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-07 11:25:10 I get popup windows and WilB's Biography script script (v1.1.3) crashes. The error given is: Thankfully it's not a new bug =) It was actually failing even in previous SMP builds, but it was failing silently (which I've finally managed to fix in the latest nightly). The core problem is the one reported by marc. While the above function seems to create an array as expected Thanks for the minimal repro sample! It should be noted though, that it's not an array, but an ActiveXObject that tries to behave as an array =) E.g. console.log(divs) will print ActiveXObject. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-07 14:04:10 It also means that html parsing in SMP version of Biography script is not working at all. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: tomaasz on 2021-02-07 14:05:38 Hi, I'm noob ... Could you send me any link where I could see how to implement JS in foobar ? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-07 14:55:32 It also means that html parsing in SMP version of Biography script is not working at all. Okay, I was totally wrong :D ActiveXObject subscript handling is just WAAAAAAAAAAAAAAY weirder than I've imagined. Everything should be working now (once the new build is done). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-07 16:03:06 Confirmed. All working without errors using: Spider Monkey Panel v1.3.2-beta+718c0702 by TheQwertiest Based on JScript Panel by marc2003 Based on WSH Panel Mod by T.P. Wang Build: 15:12:55, Feb 7 2021 Columns UI SDK Version: 6.5 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-02-08 19:11:50 There is an inconsistency between the GdiGraphics DrawLine() and FillSolidRect() methods, or at least it looks like an inconsistency to me. If I write the following code, the line looks 1 pixel longer than the rectangle: Code: [Select] include(fb.ComponentPath + "docs\\helpers.js");function on_paint(gr){ let x = 50; let y = 100; let w = 300; let h = 100; gr.FillSolidRect(x, y, w, h, colours.LightGray); gr.DrawLine(x, y, x + w, y, 1, colours.Black)} This only happens when the line is 1 pixel thick. Thicker lines perfectly patch the rectangle side of the same nominal length. Does this have a purpose? or am I overlooking something? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-02-08 20:14:46 xywh are passed along untouched so any issues you have with the component would be apparent in pure C++ too. Address any complaints to Microsoft. Just draw 2 rectangles to ensure consistency. Code: [Select] gr.FillSolidRect(x, y, w, h, colours.LightGray);gr.FillSolidRect(x, y, w, 1, colours.Black) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-09 01:33:39 The drag n drop sample just redirects the action to another playlist by Id. Yes, it does (unless you block it by changing Effect to DROPEFFECT_NONE). can not simply get the handle list of the drag n drop action without sending it to a playlist Yes, you can't. As I've said in the previous post, your feature request is acknowledged and will be implemented sometime in the future (i.e. it's a totally valid use-case and not a niche feature). My first request was about getting paths of arbitrary objects (path of a playlist file for ex.), not getting the handle list of the tracks (I thought this was already possible). But good to know. Thanks! By the way, Quote How do you save a playlist to a path? I found nothing about that on the documentation only SavePlaylist() and using a main menu command I can not add the path. Quote Not sure I want to add this method, but I will put it on the maybe list in case I change my mind (it does happen =)). And hope you reconsider this one. Along getting the handle of an fpl playlist without loading it first. Have noticed playlist are really slow to load as m3u8 files while working on the playlist manager, which means it loses its use for big playlists. It can easily take a minute for +1000 tracks when loading them, while loading the same fpl playlist it's a matter of seconds. There is no workaround for fpl playlists for auto-saving except forcing the user to manually save the playlist to fpl every time. Or converting the playlist to m3u8 (what I did) and then taking the speed penalty. It really seems strange to me to create a playlist manager which greatly simplifies management of offline playlist within foobar but having no full support for its native format. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-02-10 08:57:17 Latest nightly seems to have changed the behavior of utils.FileTest for folders. Before I could check for the existence of a folder by doing utils.FileTest(path, 'd') and it would return false if the path did not exist. Now it crashes if path does not exist with "Path does not point to a valid location". Had to alter all my checks for folder existence need to be utils.FileTest(path, 'e') && utils.FileTest(path, 'd'). Not a huge deal, but might trip some people up. Unfortunately for me I was redoing some of my folder paths at the exact same time I upgraded so I spent an hour banging my head against the wall thinking I'd screwed up the new paths somehow haha. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-10 09:10:31 Latest nightly seems to have changed the behavior of utils.FileTest for folders. Before I could check for the existence of a folder by doing utils.FileTest(path, 'd') and it would return false if the path did not exist. Now it crashes if path does not exist with "Path does not point to a valid location". Had to alter all my checks for folder existence need to be utils.FileTest(path, 'e') && utils.FileTest(path, 'd'). Not a huge deal, but might trip some people up. Unfortunately for me I was redoing some of my folder paths at the exact same time I upgraded so I spent an hour banging my head against the wall thinking I'd screwed up the new paths somehow haha. Yep, this: https://github.com/TheQwertiest/foo_spider_monkey_panel/commit/718c07024a842ef137eef2b1d91976805944c3a5 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-02-10 09:11:14 On a related note, I'm trying to find a way to get all the subfolders of a folder. Seems like fso is the way to go. fso.GetFolder(path) works fine, and .SubFolders appears to be a valid property (and should be a collection of Folders objects) but once I've got that, I can't figure out how to parse those into names/paths. fso.GetFolder(path).SubFolders doesn't work with any array methods, and fso.GetFolder(path).SubFolders.toString() gives me an invalid number of parameters error. Anyone know how this can work? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: zeremy on 2021-02-10 09:27:43 On a related note, I'm trying to find a way to get all the subfolders of a folder. Seems like fso is the way to go. fso.GetFolder(path) works fine, and .SubFolders appears to be a valid property (and should be a collection of Folders objects) but once I've got that, I can't figure out how to parse those into names/paths. fso.GetFolder(path).SubFolders doesn't work with any array methods, and fso.GetFolder(path).SubFolders.toString() gives me an invalid number of parameters error. Anyone know how this can work? Relative implementation https://github.com/smoralis/footuner/blob/af0026910091e77f3e18e59a25411054936760aa/profile/themes/footuner/js/recorder.js#L211 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-02-10 15:33:26 Relative implementation https://github.com/smoralis/footuner/blob/af0026910091e77f3e18e59a25411054936760aa/profile/themes/footuner/js/recorder.js#L211 That worked. Thanks so much! I would have never figured that out on my own. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-10 21:57:46 Latest nightly seems to have changed the behavior of utils.FileTest for folders. Should be fixed in the latest nightly. On a related note, I'm trying to find a way to get all the subfolders of a folder. Seems like fso is the way to go. Relative implementation https://github.com/smoralis/footuner/blob/af0026910091e77f3e18e59a25411054936760aa/profile/themes/footuner/js/recorder.js#L211 I've added iterator support to iterable ActiveXObjects. Now you can write it like this: Code: [Select] for (let f of p.SubFolders) { DoSmth(f);} Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-10 22:01:48 On a related note, I'm trying to find a way to get all the subfolders of a folder. Seems like fso is the way to go. fso.GetFolder(path) works fine, and .SubFolders appears to be a valid property (and should be a collection of Folders objects) but once I've got that, I can't figure out how to parse those into names/paths. fso.GetFolder(path).SubFolders doesn't work with any array methods, and fso.GetFolder(path).SubFolders.toString() gives me an invalid number of parameters error. Anyone know how this can work? And there you got another way: https://docs.microsoft.com/en-us/windows/win32/shell/folderitem-isfolder Code: [Select] const app = new ActiveXObject('Shell.Application');const items = app.NameSpace(path).Items();const numItems = items.Count;for (let i = 0; i < numItems; i++) { if (items.Item(i).IsFolder){ console.log(items.Item(i).Path); }} You can also filter the items with flags https://docs.microsoft.com/en-us/windows/win32/shell/folderitems3-filter https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-_shcontf Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-10 23:50:21 Code: [Select] const app = new ActiveXObject('Shell.Application');const items = app.NameSpace(path).Items();const numItems = items.Count;for (let i = 0; i < numItems; i++) { if (items.Item(i).IsFolder){ console.log(items.Item(i).Path); }} Funnily enough, app.NameSpace(path).Items() is not iterable, even though it's subscriptable... Gotta love those WinAPI interfaces... Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-02-11 04:28:52 Should be fixed in the latest nightly. Verified. Wasn't a big deal for me since I was always using a IsFolder() helper method so it was a one line fix, but this is still simpler. Quote I've added iterator support to iterable ActiveXObjects. Now you can write it like this: Code: [Select] for (let f of p.SubFolders) { DoSmth(f);} Much cleaner. Thanks so much! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-11 13:23:54 I'm experimenting with getters and setters in classes. The following code crashes foobar (crash reports submitted). What am I doing wrong? class _procNewFiles{ constructor() { this.state = -1; this.myHandles; this.folders = []; } get state() { return this.state; } set state(v) { this.state = v; } } Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-11 13:48:09 I'm experimenting with getters and setters in classes. The following code crashes foobar (crash reports submitted). What am I doing wrong? What version of SMP are you using? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-11 14:00:54 Spider Monkey Panel v1.3.2-beta+718c0702 by TheQwertiest Based on JScript Panel by marc2003 Based on WSH Panel Mod by T.P. Wang Build: 15:12:55, Feb 7 2021 Columns UI SDK Version: 6.5 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-11 14:04:32 Spider Monkey Panel v1.3.2-beta+718c0702 by TheQwertiest Based on JScript Panel by marc2003 Based on WSH Panel Mod by T.P. Wang Build: 15:12:55, Feb 7 2021 Columns UI SDK Version: 6.5 Can you pm me a crash dump? (latest .dmp file from foobar2000/crash reports) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-11 14:23:24 I'm experimenting with getters and setters in classes. The following code crashes foobar (crash reports submitted). What am I doing wrong? class _procNewFiles{ constructor() { this.state = -1; this.myHandles; this.folders = []; } get state() { return this.state; } set state(v) { this.state = v; } } Also, are you sure that this is the whole script that you are executing? And not just a part of it? I need the full script if I want to repro the crash. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-11 14:43:35 Also, are you sure that this is the whole script that you are executing? And not just a part of it? I need the full script if I want to repro the crash. I've PMed you a link. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-02-11 14:59:58 I'm experimenting with getters and setters in classes. The following code crashes foobar (crash reports submitted). What am I doing wrong? class _procNewFiles{ constructor() { this.state = -1; this.myHandles; this.folders = []; } get state() { return this.state; } set state(v) { this.state = v; } } Not an expert here, but I think the problem is that the getter and setter can not have the same name as the property they read and write. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: Black_Over_Bills_Mothers on 2021-02-11 15:16:40 I'm experimenting with getters and setters in classes. The following code crashes foobar (crash reports submitted). What am I doing wrong? class _procNewFiles{ constructor() { this.state = -1; this.myHandles; this.folders = []; } get state() { return this.state; } set state(v) { this.state = v; } } Not an expert here, but I think the problem is that the getter and setter can not have the same name as the property they read and write. Hey. That fixed it. Many thanks. I'm sure TheQwertiest will fix the crash though. I would have thought MS Code would flag it as an error but it didn't. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-02-11 16:22:00 I'm experimenting with getters and setters in classes. The following code crashes foobar (crash reports submitted). What am I doing wrong? class _procNewFiles{ constructor() { this.state = -1; this.myHandles; this.folders = []; } get state() { return this.state; } set state(v) { this.state = v; } } Not an expert here, but I think the problem is that the getter and setter can not have the same name as the property they read and write. There's nothing illegal about having the getter/setter return the same property... it's just almost always not what you intend to do unless you're doing something fancy and intentional like lazy getters, etc. As written, his getter would return the function (or possibly the constructor has overwritten the getter? I probably should know this), and his setter would overwrite the getter if it still exists. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-11 16:59:33 Just a question, I have not checked your latest changes on the properties panel so I don't know if it's relevant. Quote -Properties descriptions change according to things set on the panel, not just the values. i.e. if you change the sort method using the contextual menu, then the description on the panel reflects the associated states dynamically. [attach type=image]18981[/attach] IMAGE HERE -> https://hydrogenaud.io/index.php?topic=120394.msg993688#msg993688 What about an on_properties_panel_change(name) callback? That way we could recreate the descriptions (and add allowed values) on the fly. Right now I have managed 2 use-cases: -User sets property A using contextual menu. -> old Property B gets removed. -> Property B gets rewritten and set according to A. Example: A: Sorting method: by Size -> B: Asc or Desc: Asc => A: Sorting method: by Name -> B: Az or Za: Az -Main script has property A with empty value -> On init, checks if A is empty. -> old Property A gets removed. -> A secondary file loads a list of values and sets the default one to property A. Description changed accordingly too. - > Property B set according to A, ... Example: A: Sorting method. (Allowed by): '' -> A: Sorting method. (Allowed by Name, by Size): size -> B: Asc or Desc Both require removing old properties and setting new ones. But that only works because I previously know all values. If the user edits the properties panel directly, on first use case this is what happens: -User sets property A using contextual menu. -> Nothing is removed because it was not empty -> Property B gets automatically rewritten according to A and set. So I get 2 times the "same" property B but with different descriptions. Since I don't know the description of the old property B because A has already changed, I can not do anything about it. A callback with the description of the property changed would solve that. I would get A description and then get the associated B description and remove it. And I'm sure the callback would be useful for other uses. Another possibilities/solutions would be: - Function to clear all properties. That way, if the panel changes, I can simply recreate all new properties at once (not having to care about what's old and what's new. -Being able to iterate all properties of a window. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: davideleo on 2021-02-11 17:01:20 There's nothing illegal about having the getter/setter return the same property... That's not what I wrote, though. The getter and the setter can return the same property, of course, but they cannot return themselves. EDIT: I just googled "lazy getters", didn't know about this pattern. I see what you mean now. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-11 17:25:33 I'm experimenting with getters and setters in classes. The following code crashes foobar (crash reports submitted). What am I doing wrong? Fixed component crash in the nightly (once it's built), now it will crash JS instead =) Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-11 17:30:45 What about an on_properties_panel_change(name) callback? This one won't be implemented: panel properties can only be changed by the SMP user and can't be changed by the SMP itself, so it makes no sense to make such callback. - Function to clear all properties. That way, if the panel changes, I can simply recreate all new properties at once (not having to care about what's old and what's new. -Being able to iterate all properties of a window. These could be implemented via properties_v2 that I've mention before (when it's done). Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-11 19:21:11 Version: 1.4.0 Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.4.0 Changelog: Spoiler (click to show/hide) Detailed description of API changes: https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/api_changes/#v140 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: MordredKLB on 2021-02-12 05:36:31 Been playing around with 1.4 and it seems pretty solid. No issues on my end. Great work! In looking at the new packages feature, and it's very interesting, but I'm wondering whether it's worth it to switch over to this distribution method. Right now users of my theme just download my repo and extract it to a specific folder (which occasionally causes issues because people can't find the profile folder). When they want to upgrade they just do the same thing and overwrite the existing files which seems to be working pretty well. At initial install they have to copy a 1-liner include command which includes a loader.js file which then does all the including of all the other .js files, etc., but then they never have to touch the config screen again. Presumably creating a package will essentially just perform the same function? It would just change where the files would need to be extracted, right? My only external assets that aren't created by the theme itself are in an /images folder so they're already segregated from the rest of the code. Are there other benefits that I'm missing? Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-12 11:01:45 First "bug": Properties tab, clicking clear and then apply does not refresh the list as it always did. The same for deleting. Also, changing the panel name when already using DefinePanel() inside the script does nothing. DefinePanel() takes priority and change gets reverted. But using DefineScript() at the same place, the panel name set at configure takes priority. Is that intended? Looks good so far! Thanks! Specially love the in memory/ from file setting. I was so tired of having to re-import the main script to load the last changes if they were on the main file. Quote Are there other benefits that I'm missing? As far as I have seen, the paths are relative. So you can include tons of files without overwriting others. Your theme for example is a single modification intended to be use standalone, but if you use different scripts it's easy to see file conflicts. For ex. when I release the graph scripts, buttons framework and the playlist manager, all of them use the same helpers. Whenever I update one of them I will have to update the entire list of files for every other release, otherwise I will have "graph scripts" expecting a version of X helper different to "playlist manager scripts". Note your users just have scrip Theme v x or Theme v Y, so upgrading means replacing X with Y and done. Other use cases involve people having script A vx and Script B vy.... and upgrading Script B should not mean replacing files from A too. But that happens right now if you use the same filenames in both releases. In a package, I would simply put my new changes in the new package and other packages would work with its own version of the 'same' files. It can be done changing manually names on include() but this greatly speeds up the thing. Most game mods work similar, they are added using relative files path. It seems that in the same spirit than "mods", the package has a description, etc. So you can explain a bit what the thing does without expecting the user will read a comment in the js file or a readme.txt. Have no idea if there are more benefits. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: kutuzof on 2021-02-12 11:17:40 If the "foo_wave_seekbar" component is installed, then when editing scripts directly in the panels themselves, the player crashes. This has been the case in recent JS releases Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: snotlicker on 2021-02-12 11:52:20 Assuming it's the same bug as I had, ListBoxX_ClassName needs updating to something unique. https://github.com/TheQwertiest/scintilla/blob/f8817063200055b8b9f7b9a7a83c30100f64c903/win32/PlatWin.cxx#L2533 Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: TheQwertiest on 2021-02-12 12:17:11 Are there other benefits that I'm missing? Well, off the top of my head: - Package is installed and unpacked automatically either via Import button or just by drug-n-dropping. So users don't need to know the "correct" location (or the correct folder structure). - Packages has persistent id, meaning that the path to package content is always persistent and can be relied upon (e.g. by other packages). - User can easily switch between packages in a single panel without needing to copy-paste script content anywhere. - Same package can be reused in multiple panels (again, without needing to copy-paste script content). First "bug": Properties tab, clicking clear and then apply does not refresh the list as it always did. The same for deleting. I'll look into it, thanks. Also, changing the panel name when already using DefinePanel() inside the script does nothing. DefinePanel() takes priority and change gets reverted. But using DefineScript() at the same place, the panel name set at configure takes priority. Is that intended? Yes, that is intended. As per docs (https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/window.html#.DefinePanel and https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/api_changes/#v140): "Note: to retain backward compatibility this method sets both script name and panel name." That's why it was marked as deprecated =) Looks good so far! Thanks! Specially love the in memory/ from file setting. I was so tired of having to re-import the main script to load the last changes if they were on the main file. Glad that you liked it :) As far as I have seen, the paths are relative. Relative path support was there even in the previous SMP versions =) The only difference is that package scripts dir is included in the search path now. Assuming it's the same bug as I had, ListBoxX_ClassName needs updating to something unique. https://github.com/TheQwertiest/scintilla/blob/f8817063200055b8b9f7b9a7a83c30100f64c903/win32/PlatWin.cxx#L2533 Thanks for the tip! Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: regor on 2021-02-12 12:31:01 Quote Relative path support was there even in the previous SMP versions =) The only difference is that package scripts dir is included in the search path now. I meant relative to the package yep. That changes many things. Quote Yes, that is intended. As per docs (https://theqwertiest.github.io/foo_spider_monkey_panel/assets/generated_files/docs/html/window.html#.DefinePanel and https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/api_changes/#v140): "Note: to retain backward compatibility this method sets both script name and panel name." That's why it was marked as deprecated =) I was not talking about the funcs, but the UI behavior. The option should be greyed out if the script contains a call to DefinePanel(), or some UI warning in the panel: NAME + (non configurable: set by script). It's counterintuitive for users to change something and be reverted without notice, since your main aim was to ease things for final users. Title: Re: Spider Monkey Panel (foo_spider_monkey_panel) Post by: cerbaire on 2021-02-12 15:57:20 Hi everyone, I have a small problem using XMLHTTP object. It generates the following error: ActiveXObject: source: msxml3.dll description: Error not specified This is an extract of the code I use to get this error (I'm using Typescript) let xhttp = new ActiveXObject("Microsoft.XMLHTTP"); return new Promise((resolve, reject) => { xhttp.onreadystatechange = function () { if (xhttp.status === 200) { if (xhttp.readyState === 4) { resolve(xhttp.responseText); } else { reject("Error"); } } else { reject("Error"); } }; const album_url = http://localhost/api/v1/album/get?album_id=${album_id};
xhttp.open("GET", album_url, true);
xhttp.send();
}
I use foo_spider_monkey_panel 1.4.0
Any idea where this error could come from ?

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-02-12 19:52:00
Any idea where this error could come from ?
It seems that it's not allowed to access status before readyState is 'Done' (i.e. equal to 4). And yes, MS should've done a much better job with the error message in such case :D
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-02-12 19:54:11
@regor , @kutuzof , all reported issues should be fixed in the dev build.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2021-02-12 21:26:01
Any idea where this error could come from ?
It seems that it's not allowed to access status before readyState is 'Done' (i.e. equal to 4). And yes, MS should've done a much better job with the error message in such case :D
Thanks @TheQwertiest, it works great now.
One question: I wonder if it is possible to package a multiple panel theme with the last release of your plug-in. It seems we can easily package a single panel theme. What if I have 5 panels ?
Many thanks for all the job you've done.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2021-02-12 22:19:12
Well, off the top of my head:
- Package is installed and unpacked automatically either via Import button or just by drug-n-dropping. So users don't need to know the "correct" location (or the correct folder structure).
- Packages has persistent id, meaning that the path to package content is always persistent and can be relied upon (e.g. by other packages).
- User can easily switch between packages in a single panel without needing to copy-paste script content anywhere.
- Same package can be reused in multiple panels (again, without needing to copy-paste script content).
Okay, so drag-n-drop is a neat feature. For that should it be a .zip file that has the package.json at the root level, or does it need to include the GUID folder as well? For upgrades, dropping/installing an updated package will overwrite the original contents I assume?

Edit: I did a bunch of tests and I can't figure out how to create a zip file package that can be installed correctly. I copied your package to a new location, changed the GUID and then zipped it up and attempted to import. Getting this error whatever basically whatever I do:
copy: The system cannot find the path specified.: "D:\Source\foobar2000_portable\foo_spider_monkey_panel\tmp\unpacked_package", "D:\Source\foobar2000_portable\foo_spider_monkey_panel\packages\{AAAAFFEF-C88A-4849-94D5-F33C71649927}"
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-02-12 23:41:38
Okay, so drag-n-drop is a neat feature. For that should it be a .zip file that has the package.json at the root level, or does it need to include the GUID folder as well? For upgrades, dropping/installing an updated package will overwrite the original contents I assume?
To create a package click "New Package" in package manager: this will create all the necessary files for the package (and this is the only proper way to create one).
To pack a package into an archive of importable format click "Export" in package manager.
Package id is used to identify a package, so importing a package with the same id will replace the current package.

What if I have 5 panels ?
You'll have to split it in at least 5 packages =)
Drag-n-drop package import support batch import as well.
Thus the whole theme could be reduced to N script packages and a .fcl file. And it's installation might be done as follows:
- User installs all the required packages (via drag-n-drop).
- User imports theme's .fcl (via fb2k preferences).

Note: common theme stuff can be extracted to a separate utility package, the one that does nothing, but is accessed via utils.GetPackagePath() from other packages.

Any file can be drag-n-dropped to the Package files control on package tab and it will automatically copied in a proper place. Note though, that folders are always put in assets folder (even if they contain only scripts), thus they have to be moved to the scripts folder manually.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2021-02-13 01:45:08
Thanks, that makes sense. So from my tests, when I update a package the entire contents of the package folder are wiped, and then the new package is extracted there.

I've been creating a config.json file with my theme so that users can non-destructively make changes for title-formatting strings without having to touch the actual code so that updates don't overwrite their changes. Seems like for me to make this work I'd need to store these config files in a different location outside the package itself. fb.ProfilePath maybe? I've also got some other assets that users tend to add their own things to so either I need to continue to use a centralized Georgia folder outside the package or maybe just continue doing things the way I've been doing them. Need to think about this a bit more.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-02-13 23:02:49
Version: 1.4.1
Changelog:
Hotfix for v1.4.0 (see changelog above (https://hydrogenaud.io/index.php?topic=116669.msg993706#msg993706))
Spoiler (click to show/hide)
Detailed description of API changes: https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/api_changes/#v141
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: JoeSyr on 2021-02-14 20:23:59
Hello, I'm experiencing a conflict between assorted SMP scripts and a setup that uses a high DPI scaling override(to make fb2k usable on large/high res screens). I'm not sure if this is more an issue with SMP or with windows, but as far as I've seen so far, SMP elements are the only ones so specifically affected so I thought to mention it here. It's not new to 1.4/1.4.1.

In a nutshell if you have:

-Win10 display settings set to use a scaling factor of >100%

-Foobar2000.exe set to override that scaling factor using "System (enhanced)" (foobar2000.exe ->properties->compatibility->change high DPI settings->High DPI scaling override)

Then a number of elements are prone to getting white box artifacts, for example the bottom bar in the StrigUI2.0 theme looks like this (https://imgur.com/9XgnLjz) after any of the buttons have been moused over (or things like the timer and the non-waveform seekbar incur it passively), and the white boxes persist until something is clicked. Similar white boxing happens to the biography panel by WilB, and the scrollbars in JS Playlist.

By comparison, using "System" instead of "system (enhanced)" does not cause these issues, but it does leave all the text in fb2k in an undesirable blurry state (as of yet I've found no other combination of windows settings that fixes this without otherwise distorted the UI to an unusable state). On my current setup (using a 4k tv as a monitor) it is necessary to use one of these or the UI will be severely distorted (and the global scaling factor is subjectively necessary to use the setup at all). This also seems to not be a driver related issue a the same thing happens on an Nvidia 2070 Super as an Intel integrated graphics build.

Somewhat related, the sample script at samples/complete/last.fm bio.js is badly rendered in such setups because the font size comes out giant even at the smallest settings.

Unrelated to these scaling related issues, I also just thought to report that 1.4 and 1.4.1 seem to break the Last.fm panel included in StrigUI2.0 with the following error message (I am not personally using/signed into this panel but I noticed it crashing while loading themes investigating the scaling issues):

this.xmlhttp is undefined

File: _LastFM.js
Line: 504, Column: 6
Stack trace:
lfm_parse_data@_LastFM.js:504:6
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-02-15 11:29:23
@JoeSyr , SMP does not handle DPI scaling in any way, i.e. everything is implemented (or not) by script authors. Since I don't have a high-DPI display, I don't even try to implement it in any of the scripts.
PS: Some sample panels do have DPI scaling code though, all thanks to marc2003 =)

Regarding StrigUI2.0 errors: this script was made by SMP user and is not a part of SMP installation, so you'll have to either request the author of the script for the fix or to fix it yourself. But it seems like a site parsing error, so perhaps last.fm changed the site structure at one point of time, which made the corresponding parsing code incompatible.

PS: It was working in previous SMP versions, because these kind of errors were suppressed before, because of the JS engine limitations (which was rectified in 1.4.0).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: JoeSyr on 2021-02-15 20:21:56
I see, thanks for the insights. I'll give things a spin to see if I can possibly adapt some of marc2003's scripts for my own usage.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-02-15 21:11:35
Somewhat related, the sample script at samples/complete/last.fm bio.js is badly rendered in such setups because the font size comes out giant even at the smallest settings.

Well this is supposed to one of the scripts with DPI support!!

All I can is that it works fine here but there are caveats:

-because the DPI is read from the registry, any desktop DPI changes means you have to log out and log back in again. It's not enough to restart the application.
-only the primary monitor can be queried. multi-monitor setups with differing DPI settings per monitor are not going to play nice.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2021-02-15 23:21:39
Whereas the GdiDrawText() method uses "segoe ui" as a fallback font for missing "segoe mdl2 assets" characters, DrawString() replaces them with empty squares. Is this a limitation of DrawString(), or am I missing something?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Black_Over_Bills_Mothers on 2021-02-16 09:13:53
I think there is an error in the documentation for IDE integration (https://theqwertiest.github.io/foo_spider_monkey_panel/docs/script_documentation/ide_integration/)

The entry under Visual Studio Code:
/// <reference path="./../../user-components/foo_spider_monkey_panel/docs/js/foo_spider_monkey_panel.js">

Should have a forward slash towards the end as below:
/// <reference path="./../../user-components/foo_spider_monkey_panel/docs/js/foo_spider_monkey_panel.js"/>
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-02-16 13:04:49
Whereas the GdiDrawText() method uses "segoe ui" as a fallback font for missing "segoe mdl2 assets" characters, DrawString() replaces them with empty squares. Is this a limitation of DrawString(), or am I missing something?

I can't be bothered to trawl the source code so I'm going to assume SMP hasn't deviated from the original WSH/JSP code where font objects have to store 2 different types of WinAPI fonts internally. Those are HFONT and Gdiplus::Font.

GdiDrawText uses HFONT and IIRC you get Arial if the font you ask for is missing
DrawString uses Gdiplus::Font and you get Microsoft Sans Serif if the font you ask for is missing

When you check the properties of any font object in JS (.Name, .Size, .Style), the internal Gdiplus::Font is queried, not the HFONT.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2021-02-16 16:34:40
...I'm going to assume SMP hasn't deviated from the original WSH/JSP code where font objects have to store 2 different types of WinAPI fonts internally. Those are HFONT and Gdiplus::Font.

JSP behaves in the same way, so I guess your assumption is correct.

DrawString uses Gdiplus::Font and you get Microsoft Sans Serif if the font you ask for is missing

Yes, if the whole font is missing, it is replaced with the fallback font, but if the font exists, missing glyphs are replaced with a □. GdiDrawText replaces them with the corresponding fallback font glyph, instead.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: snotlicker on 2021-02-16 20:05:52
Since that font is for symbols only, why don't you limit yourself to what is actually there? I presume you're using charmap to get what you want?

Maybe a practical example will help me understand??
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2021-02-16 21:31:46
Since that font is for symbols only, why don't you limit yourself to what is actually there?

Yes, I suppose that's the proper way to go. The idea of relying on the fallback font arises from the need to simplify a few graphical issues when drawing captions (buttons, headers, etc.) with both an icon and a text label. Since I set their dimensions with relative values, based on MeasureStringInfo properties, dealing with just one font makes things easier. With "segoe ui symbol" this was not a problem, because the font provides all the regular "segoe ui" characters. When I moved to "segoe mdl2 assets", which I like better and has many more fonticons, I didn't even realize this was an issue because I was always using GdiDrawText (I actually did mistake the "arial" fallback font for "segoe ui"). Now I made some changes in the scripts, which require using DrawString, though, and here I am.

It's not really a coding problem in a strict sense, I just wanted to make sure I was not overlooking some options available to make DrawString behave like GdiDrawText in this regard, but the more I think about it and the less I like the idea of relying on a fallback font anyway.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2021-02-20 06:42:14
In 1.4.1 if I set Script source as file, and then select a file everything works. But when I restart foobar my file selection has lost everything except for what appears to be fb.profilePath. So no file is selected and I get an error and am forced to reselect the file (https://i.imgur.com/LLx0F70.png). Interestingly when I go back into the file selection dialog it does remember the full path to the file I had last selected.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-02-20 09:46:13
In 1.4.1 if I set Script source as file, and then select a file everything works. But when I restart foobar my file selection has lost everything except for what appears to be fb.profilePath. So no file is selected and I get an error and am forced to reselect the file (https://i.imgur.com/LLx0F70.png). Interestingly when I go back into the file selection dialog it does remember the full path to the file I had last selected.
Can you provide the full path to file you are trying to use?

And can you try the latest dev build and see if it has the same error?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2021-02-20 17:55:54
Can you provide the full path to file you are trying to use?

And can you try the latest dev build and see if it has the same error?
Full path is: D:\Source\foobar2000_portable\georgia\georgia-theme.js

Still seeing the same thing in 1.4.2-dev
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2021-02-21 13:12:40
Full path is: D:\Source\foobar2000_portable\georgia\georgia-theme.js

Still seeing the same thing in 1.4.2-dev
Hm... Still can't reproduce...
Can you try the following custom build?
https://ci.appveyor.com/api/buildjobs/dmess6a7ifkhdl12/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel.fb2k-component
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2021-02-21 16:04:47
Hm... Still can't reproduce...
Can you try the following custom build?
https://ci.appveyor.com/api/buildjobs/dmess6a7ifkhdl12/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel.fb2k-component
No joy. I tried this on a non-portable installation and everything worked fine. Can't tell if that's the issue, if it's another component (UIHacks?) or if something just got in a bad state when I was experimenting with packages and now it can't get out.

Edit: I completely removed FSM including the packages folders, then reinstalled and the path seems to survive th