I wrote an keyboard input script for editing tags. It works (reasonably) well in foobar2000 v0.9.6.9 with wsh panel mod v1.2.1. With foobar2000 v.1.0 with wsh panel mod v1.2.2 beta 3, though, it gives a script error saying "Error: WSH Panel Mod (GUID: 55AB069D-B0DA-4E6B-84AB-287C6123DCC3): Microsoft JScript runtime error: Overflow Ln: 159, Col: 3 <no source text available>". The line number doesn't make much sense to me, because it is in the middle of a switch statement:
inputobjects = [];
// ==PREPROCESSOR==
// Include jquery here
// @import "%fb2k_path%scripts\Flags.txt"
// @import "%fb2k_path%scripts\Helpers.txt"
// @import "%fb2k_path%scripts\inputobjects.js"
// @import "%fb2k_path%scripts\values.js"
// ==/PREPROCESSOR==
function inputobjectsDraw(gr) {
for (i in inputobjects) {
inputobjects[i].draw(gr);
}
}
function inputobjectsRedraw() {
for (i in inputobjects) {
inputobjects[i].redraw();
}
}
function inputobjectsLoad() {
if ((g_handle.Path != fpath) || (reload)) {
reload = false;
fpath = g_handle.Path;
for (i in inputobjects) {
inputobjects[i].load();
}
}
}
function inputobjectsSave() {
for (i in inputobjects) {
inputobjects[i].save();
}
}
// --- APPLICATION START
var g_handle = fb.GetFocusItem();
window.WatchMetadb(g_handle);
var metadata = g_handle.GetFileInfo();
reload = true;
fpath = "";
edit = false;
function on_mouse_move(x, y) {
hoverbak = cursorhover;
cursorhover = false;
for (i in inputobjects) {
inputobjects[i].onMove(x, y);
};
if (hoverbak != cursorhover) {
if (cursorhover)
window.SetCursor(32649);
else
window.SetCursor(32512);
}
}
function on_mouse_lbtn_down(x, y) {
for (i in inputobjects) {
inputobjects[i].onClick(x, y);
};
inputobjectsRedraw();
}
function on_focus(is_focused) {
if (!is_focused && edit) inputobjectsSave();
}
function on_item_focus_change() {
if (edit) inputobjectsSave();
window.UnWatchMetadb();
g_handle = fb.GetFocusItem();
window.WatchMetadb(g_handle);
metadata = g_handle.GetFileInfo();
reload = true;
inputobjectsRedraw();
}
function on_metadb_changed(g_handle, fromhook) {
metadata = g_handle.GetFileInfo();
reload = true;
inputobjectsRedraw();
}
function on_size() {
for (i in inputobjects) {
inputobjects[i].resize();
}
}
function on_paint(gr) {
gr.FillSolidRect(0, 0, window.Width, window.Height, RGB(0,0,0));
gr.DrawRect(1, 1, window.Width - 3, window.Height - 3, 3, RGB(255, 255, 255));
inputobjectsLoad();
inputobjectsDraw(gr);
}
//Relates to: Inputbox
function on_key_down(vkey) {
key = vkey;
ins = "";
tb = null;
//edit, ctrl, alt?
if (edit && !utils.IsKeyPressed(17) && !utils.IsKeyPressed(18)){
for (i in inputobjects) {
tb = inputobjects[i];
if ((tb.type == "ib") && tb.active) break;
}
if ((tb.type == "ib") && tb.active) {
if (!tb.special) {
//0-9
if (47<key && key<58 && !utils.IsKeyPressed(16)) {
ins = String.fromCharCode(key);
}
//A-Z
if (64<key && key<91) {
if (utils.IsKeyPressed(16))
ins = String.fromCharCode(key);
else
ins = String.fromCharCode(key + 32);
}
//Num
switch (key){
case 96: ins = "0"; break;
case 97: ins = "1"; break;
case 98: ins = "2"; break;
case 99: ins = "3"; break;
case 100: ins = "4"; break;
case 101: ins = "5"; break;
case 102: ins = "6"; break;
case 103: ins = "7"; break;
case 104: ins = "8"; break;
case 105: ins = "9"; break;
case 106: ins = "*"; break;
case 107: ins = "+"; break;
case 109: ins = "-"; break;
case 110: ins = "."; break;
case 111: ins = "/"; break;
}
//simple characters
if (!utils.IsKeyPressed(16)) {
switch (key){
case 189: ins = "-"; break;
case 187: ins = "="; break;
case 219: ins = "["; break;
case 221: ins = "]"; break;
case 186: ins = ";"; break;
case 220: ins = "\\"; break;
case 226: ins = "\\"; break;
case 188: ins = ","; break;
case 190: ins = "."; break;
case 191: ins = "/"; break;
}
}
//simple shift characters
if (utils.IsKeyPressed(16)) {
switch (key){
case 49: ins = "!"; break;
case 50: ins = "@"; break;
case 51: ins = "#"; break;
case 52: ins = "$"; break;
case 53: ins = "%"; break;
case 55: ins = "&"; break;
case 56: ins = "*"; break;
case 57: ins = "("; break;
case 48: ins = ")"; break;
case 189: ins = "_"; break;
case 187: ins = "+"; break;
case 219: ins = "{"; break;
case 221: ins = "}"; break;
case 186: ins = ":"; break;
case 220: ins = "|"; break;
case 226: ins = "|"; break;
case 188: ins = "<"; break;
case 190: ins = ">"; break;
case 191: ins = "?"; break;
}
}
//special characters
if (!utils.IsKeyPressed(16)) {
switch (key){
case 192: tb.special = true; tb.specialchar = "`"; break;
case 222: tb.special = true; tb.specialchar = "'"; break;
}
}
//special shift characters
if (utils.IsKeyPressed(16)) {
switch (key){
case 192: tb.special = true; tb.specialchar = "~"; break;
case 54: tb.special = true; tb.specialchar = "^"; break;
case 222: tb.special = true; tb.specialchar = "\""; break;
}
}
//space
if (key == 32){
ins = String.fromCharCode(key);
}
}
else {
ins0 = tb.specialchar;
//special characters
switch (key){
case 65:
switch (tb.specialchar){
case "~": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ã" : ins = "ã"; key = null; break;
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "À" : ins = "à"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Â" : ins = "â"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ä" : ins = "ä"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Á" : ins = "á"; key = null; break;
}
break;
case 67:
switch (tb.specialchar){
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ç" : ins = "ç"; key = null; break;
}
break;
case 69:
switch (tb.specialchar){
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "È" : ins = "è"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ê" : ins = "ê"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ë" : ins = "ë"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "É" : ins = "é"; key = null; break;
}
break;
case 73:
switch (tb.specialchar){
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ì" : ins = "ì"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Î" : ins = "î"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ï" : ins = "ï"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "í" : ins = "í"; key = null; break;
}
break;
case 78:
switch (tb.specialchar){
case "~": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ñ" : ins = "ñ"; key = null; break;
}
break;
case 79:
switch (tb.specialchar){
case "~": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Õ" : ins = "õ"; key = null; break;
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ò" : ins = "ò"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ô" : ins = "ô"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ö" : ins = "ö"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ó" : ins = "ó"; key = null; break;
}
break;
case 83:
switch (tb.specialchar){
case "\"": if (!utils.IsKeyPressed(16)) {ins0 = ""; ins = "ß"; key = null}; break;
}
break;
case 85:
switch (tb.specialchar){
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ù" : ins = "ù"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Û" : ins = "û"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ü" : ins = "ü"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ú" : ins = "ú"; key = null; break;
}
break;
case 89:
switch (tb.specialchar){
case "\"": if (!utils.IsKeyPressed(16)) {ins0 = ""; ins = "ÿ"; key = null}; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ý" : ins = "ý"; key = null; break;
}
break;
}
//0-9
if (47<key && key<58 && !utils.IsKeyPressed(16)) {
ins = String.fromCharCode(key);
}
//A-Z
if (64<key && key<91) {
if (utils.IsKeyPressed(16))
ins = String.fromCharCode(key);
else
ins = String.fromCharCode(key + 32);
}
//Num
switch (key){
case 96: ins = "0"; break;
case 97: ins = "1"; break;
case 98: ins = "2"; break;
case 99: ins = "3"; break;
case 100: ins = "4"; break;
case 101: ins = "5"; break;
case 102: ins = "6"; break;
case 103: ins = "7"; break;
case 104: ins = "8"; break;
case 105: ins = "9"; break;
case 106: ins = "*"; break;
case 107: ins = "+"; break;
case 109: ins = "-"; break;
case 110: ins = "."; break;
case 111: ins = "/"; break;
}
//simple characters
if (!utils.IsKeyPressed(16)) {
switch (key){
case 189: ins = "-"; break;
case 187: ins = "="; break;
case 219: ins = "["; break;
case 221: ins = "]"; break;
case 186: ins = ";"; break;
case 220: ins = "\\"; break;
case 226: ins = "\\"; break;
case 188: ins = ","; break;
case 190: ins = "."; break;
case 191: ins = "/"; break;
}
}
//simple shift characters
if (utils.IsKeyPressed(16)) {
switch (key){
case 49: ins = "!"; break;
case 50: ins = "@"; break;
case 51: ins = "#"; break;
case 52: ins = "$"; break;
case 53: ins = "%"; break;
case 55: ins = "&"; break;
case 56: ins = "*"; break;
case 57: ins = "("; break;
case 48: ins = ")"; break;
case 189: ins = "_"; break;
case 187: ins = "+"; break;
case 219: ins = "{"; break;
case 221: ins = "}"; break;
case 186: ins = ":"; break;
case 220: ins = "|"; break;
case 226: ins = "|"; break;
case 188: ins = "<"; break;
case 190: ins = ">"; break;
case 191: ins = "?"; break;
}
}
tmp = ins
ins = ins0 + tmp;
tb.special = false;
tb.specialchar = "";
}
//left
if (key == 37){
if (tb.cursor != 0) tb.cursor -= 1;
}
//right
if (key == 39){
if (tb.cursor != tb.contentedit.length) tb.cursor += 1;
}
//up
if (key == 38){
tb.up = true;
}
//down
if (key == 40){
tb.down = true;
}
//home
if (key == 36){
tb.cursor = 0;
}
//end
if (key == 35){
tb.cursor = tb.contentedit.length;
}
//backspace
if (key == 8){
if (tb.cursor != 0){
str2 = tb.contentedit.slice(tb.cursor);
tb.cursor -= 1;
str1 = tb.contentedit.slice (0, tb.cursor);
tb.contentedit = str1 + str2
}
}
//delete
if (key == 46){
if (tb.cursor != tb.contentedit.length){
str2 = tb.contentedit.slice(tb.cursor + 1);
str1 = tb.contentedit.slice (0, tb.cursor);
tb.contentedit = str1 + str2
}
}
//enter
if (key == 13) {
inputobjectsSave();
}
//esc
if (key == 27) {
tb.escape();
}
str1 = tb.contentedit.slice(0, tb.cursor);
str2 = tb.contentedit.slice(tb.cursor);
tb.contentedit = str1 + ins + str2;
tb.cursor += ins.length;
tb.splitagain = true;
tb.redraw();
}
}
}
inputobjects[0] = new Buttons (15, 10);
inputobjects[1] = new SplitterInputBox("artist", "artist", "separators", 10, 10, 80, "window.Width - 230", 40, 10);
inputobjects[2] = new InputBox("conductor", "conductor", true, "window.Width / 2 + 10", 60, 80, "window.Width / 2 - 100", 30, 10);
inputobjects[3] = new InputBox("composer", "composer", true, 10, 60, 80, "window.Width / 2 - 100", 30, 10);
inputobjects[4] = new InputBox("performer", "performer", true, 10, 100, 80, "window.Width - 100", 30, 10);
inputobjects[5] = new CheckBox("TAC", "tac", "window.Width - 111", 140, 50, 30, 10);
inputobjects[6] = new InputRating("rating", "rating", 5, "window.Width - 400", 140, 70, 30, 10);
inputobjects[7] = new Keywords("country", "country", countrycodes, countrynames, 10, 140, 80, "window.Width - 490", 30, 10);
inputobjects[8] = new InputBox("title", "title", false, 10, 180, 80, "window.Width - 100", 40, 10);
inputobjects[9] = new InputBox("year", "date", false, "window.Width - 160", 230, 60, 90, 30, 10);
inputobjects[10] = new InputBox("disc", "discnumber", false, "window.Width - 280", 230, 50, 70, 30, 10);
inputobjects[11] = new InputBox("track", "tracknumber", false, "window.Width - 410", 230, 50, 70, 30, 10);
inputobjects[12] = new InputBox("-", "album", false, "window.Width / 3 + 10", 230, 20, "2 * window.Width / 3 - 455", 30, 10);
inputobjects[13] = new InputBox("album", "album artist", false, 10, 230, 80, "window.Width / 3 - 95", 30, 10);
inputobjects[14] = new InputBox("year", "original release date", false, "window.Width - 160", 270, 60, 90, 30, 10);
inputobjects[15] = new InputBox("taken from", "original album", false, "window.Width / 3 - 55", 270, 85, "2 * window.Width / 3 - 190", 30, 10);
inputobjects[16] = new InputBox("label", "publisher", true, 10, 270, 80, "window.Width / 3 - 165", 30, 10);
inputobjects[17] = new Keywords("signature", "signature", signatures, signatures, "window.Width - 310", 330, 80, 220, 30, 10);
inputobjects[18] = new Keywords("language", "language", languagecodes, languagenames, "(window.Width - 330) / 2", 330, 80, "(window.Width - 330) / 2 - 70", 30, 10);
inputobjects[19] = new Keywords("vocals", "vocals", vocalsshort, vocalslong, 10, 330, 80, "(window.Width - 330) / 2 - 100", 30, 10);
inputobjects[20] = new RadioBox("category", "category", categories, categories, "window.Width - 686", 370, 80, 0, 30, 10, true);
inputobjects[21] = new Keywords("genre", "genre", genres, genres, 10, 370, 80, "window.Width - 786", 30, 10);
inputobjects[22] = new Keywords("mood", "mood", moods, moods, "window.Width / 2 + 10", 410, 80, "window.Width / 2 - 110", 30, 10);
inputobjects[23] = new Keywords("subgenre", "subgenre", subgenres, subgenres, 10, 410, 80, "window.Width / 2 - 100", 30, 10);
inputobjects[24] = new InputBox("style", "style", false, 10, 450, 80, "window.Width - 100", 30, 10);
inputobjects[25] = new ShowMultiLine("comment", "comment", 10, 510, 80, "window.Width - 110", "Math.floor((window.Height - 520) / 40)", 30, 10);
load = false;
cursorhover = false;
Is this a bug or is there something wrong with my code?
Of course my script would be much better if there was something like an input box interface, so that is a feature I would like to request Or is there already a way to implement it and am I missing it ?