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:'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:// *****************************************************************************************************************************************
// 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.