Hydrogenaudio Forums

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, external images, lines, rectangles, etc.
 - Access fonts and colours settings from the main preferences of CUI/DUI.
 - Execution of main menu and context menu commands.
 - Creation of custom buttons and menus.
 - Capture of keystrokes/mouse movement/clicks.
 - Capture of foobar2000 events with callbacks.
 - Processing and changing of file tags.
 - Playlists management: create, destroy, sort, change, rename and do anything that fb2k can do.
 - Access Media Library with ability to sort and filter it's contents.
 - Per panel settings storage.
 - Built-in web and filesystem access.
 - And more!

Getting started!
 - Use Installation Guide (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/Installation).
 - Take a look at Documentation and Samples (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/Script-documentation)

JScript Panel users
Spoiler (click to show/hide)

Links
 - Download link (https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/latest)
 - Changelog (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/CHANGELOG.md)
 - Detailed list of API Changes (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes)
 - Wiki (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki)
 - Current tasks and plans (https://github.com/TheQwertiest/foo_spider_monkey_panel/projects/1)
 - Nightly 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/marc2k3/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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.0
Changelog (relative to the latest version of JScript Panel (https://github.com/marc2k3/foo_jscript_panel)):
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 function

File: <main>
Line: 35, Column: 3

Stack trace:
   on_playback_new_track @ <main>: 35: 3
How to adapt this :
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!

@WilB, You just knew someone would ask 'What about porting your wonderful Biography panel'.....
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();

How to adapt this :
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;
    fb.RunContextCommandWithMetadb("ReplayGain/Scan as albums (by folders)",plman.GetPlaylistSelectedItems(plman.ActivePlaylist));

gives this error;
'RunContextCommandWithMetadb' failed:
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;
    fb.RunContextCommandWithMetadb("ReplayGain/Scan as albums (by folders)",plman.GetPlaylistSelectedItems(plman.ActivePlaylist));

gives this error;
'RunContextCommandWithMetadb' failed:
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
You just knew someone would ask 'What about porting your wonderful Biography panel'.....

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
You just knew someone would ask 'What about porting your wonderful Biography panel'.....

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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.2
Changelog
Hotfix for v1.0.1 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg963027.html#msg963027))
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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.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 HOTKEYS
function 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 HOTKEYS
function 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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.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...

Quote from: samples/readme.md
- "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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.1
Changelog
Hotfix for v1.1.0 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg965016.html#msg965016))
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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.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.

Full answer:
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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.4
Changelog
Hotfix for v1.1.3 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg967258.html#msg967258))
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
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.5
Changelog
Hotfix II for v1.1.3 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg967258.html#msg967258))
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.

Not sure what / if you can do anything about this, but mentioning just in case.

(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?

PS: @zeremy thanks for all the answers in this thread =)
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 = 0
var 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 hide
var 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))
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): InvalidParameter

File: <main>
Line: 45, Column: 2

Stack 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.

Thanks in advance
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).
SimplePortal 1.0.0 RC1 © 2008-2019