=== 目次 ===
Spider Monkey Panelとは?
Spider Monkey Panelとはfoobarのサードパーティの拡張子コンポーネントのひとつで、JScriptというプログラミング言語を実行するパネルを追加することができます。よって、JScriptで記述さえできれば、「タグを変更するボタン」の追加も可能です。
この記事ではタグを変更するボタンの実装方法を紹介します。
動作にはColumns UIが必要
Spider Monkey PanelはColumns UIのパネルとして動作しますので、Columns UIが事前にインストールされている必要があります。Columns UIのインストールなどは以下の記事にまとめているので、そちらをご覧ください。
Spider Monkey Panelをインストールする
Spider Monkey Panelのコンポーネントは以下のURLからダウンロード可能です。https://github.com/TheQwertiest/foo_spider_monkey_panel/releases
最新版のコンポーネントをダウンロードしたら、通常のコンポーネントと同様にfoobarに追加すればOKです。
コンポーネント追加後は再起動するようにfoobarから言われますので、再起動しましょう。
これでSpider Monkey Panelのインストールは完了です。
Spider Monkey PanelのパネルをColumns UIのレイアウトに追加する
まずはSpider Monkey PanelのパネルをColumns UIのレイアウトに追加しましょう。追加方法は通常のColumns UIのレイアウト追加と同じです。
よく分からない方は以下の記事にまとめていますので、そちらをご覧ください。
下図はColumns UIのレイアウトに追加した例です。

タグを編集するボタンを追加する
本題のタグを編集するボタンの追加方法を紹介します。私はボーカルなしの曲に「/ Instrumental」というワードを付与して曲を管理しているのですが、「コメントに / Instrumental というワードを付与するボタン」を自分で実装して作業を楽にしています。
以下では「コメントに / Instrumental というワードを付与するボタン」を例として、ボタンの追加方法を紹介します。
ボタン用の画像を用意する
JScriptのコードを入力する前にボタン用の画像を用意しましょう。以下のようなサイトを利用すると簡単にボタン用の画像が作成できます。
https://text-img.cman.jp/
以下の例では下の画像をボタンとして使用します。

ボタン用の画像を作成したら、パソコンの適当なところに保存します。
JScriptのコードを入力する
追加したSpider Monkey Panelのパネルに対して、JScriptのコードを入力していきましょう。追加したパネル上で右クリック -> Edit panel script…を選択します。

すると、下図のようにエディターが立ち上がります。

そうしましたら、エディターに以下のコードをコピペしてください。
画像フォルダパス(IMAGE_DIR_PATH)と画像ファイル名(Instrumental.png)は自分の環境に併せて編集してください。
'use strict';
var IMAGE_DIR_PATH = "D:\\foobar2000\\MyButtonJScript\\";
function addMeta(tag, value) {
console.log("\naddMeta STARTED");
var handles = plman.GetPlaylistSelectedItems(plman.ActivePlaylist);
console.log(handles);
var arr = [];
for(var i=0; i<handles.Count; i++) {
console.log("Roop: " + i);
var info = handles[i].GetFileInfo();
var OldValue = info.MetaValue(info.MetaFind(tag), 0);
console.log("OldValue: " + OldValue);
var NewValue = OldValue;
if(OldValue.indexOf(value) != -1) {
console.log("Tag already has value");
} else {
NewValue = NewValue + " / " + value;
}
console.log("NewValue: " + NewValue);
arr.push({[tag] : NewValue});
}
var json = JSON.stringify(arr);
console.log("JSON: " + json);
handles.UpdateFileInfoFromJSON(json);
console.log("addMeta FINISHED");
}
window.DefineScript('Tag buttons', {author:'aresei-note.com', options:{grab_focus:false}});
include(fb.ComponentPath + 'samples\\complete\\js\\lodash.min.js');
include(fb.ComponentPath + 'samples\\complete\\js\\helpers.js');
include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');
let panel = new _panel(true);
let ButtonAddInstrumental = new _buttons();
ButtonAddInstrumental.buttons.menu = new _button(
0, 5, 145, 25,
{normal : IMAGE_DIR_PATH + "Instrumental.png"}
);
function on_paint(gr) {
panel.paint(gr);
ButtonAddInstrumental.paint(gr);
}
function on_mouse_move(x, y) {
ButtonAddInstrumental.move(x, y);
}
function on_mouse_leave() {
ButtonAddInstrumental.leave();
}
function on_mouse_lbtn_up(x, y, mask) {
if(ButtonAddInstrumental.buttons.menu.trace(x,y)) {
console.log("click instrumental button");
addMeta("comment", "Instrumental");
}
return true;
}
うまくいくと、下図のようにボタンが追加されました。

ボタンを押す前が下図の状態だとします。

ボタンを押すと、下図のようにコメントに / Instrumentalを付与できました。超便利ですね。

コメント以外を編集するには?
コメント以外のタグを編集したい場合はon_mouse_lbtn_up内のaddMetaの第1引数を変えてください。function on_mouse_lbtn_up(x, y, mask) {
if(ButtonAddInstrumental.buttons.menu.trace(x,y)) {
console.log("click instrumental button");
addMeta("comment", "Instrumental"); //ここです
}
return true;
}
例えば、ジャンルならば”genre”とします。
付与する文字列を変更したい場合は?
したい場合はon_mouse_lbtn_up内のaddMetaの第2引数を変えてください。function on_mouse_lbtn_up(x, y, mask) {
if(ButtonAddInstrumental.buttons.menu.trace(x,y)) {
console.log("click instrumental button");
addMeta("comment", "Instrumental"); //ここです
}
return true;
}
付与ではなく書き換えたい場合は?
addMetaの内容を以下のように書き換えてください。function addMeta(tag, value) {
console.log("\naddMeta STARTED");
var handles = plman.GetPlaylistSelectedItems(plman.ActivePlaylist);
console.log(handles);
var arr = [];
for(var i=0; i<handles.Count; i++) {
console.log("Roop: " + i);
var info = handles[i].GetFileInfo();
var OldValue = info.MetaValue(info.MetaFind(tag), 0);
console.log("OldValue: " + OldValue);
var NewValue = value;
console.log("NewValue: " + NewValue);
arr.push({[tag] : NewValue});
}
var json = JSON.stringify(arr);
console.log("JSON: " + json);
handles.UpdateFileInfoFromJSON(json);
console.log("addMeta FINISHED");
}
複数のボタンを表示するには?
ボタンの追加およびイベント処理をボタンの数だけ増やせばOKです。煩雑なので解説しませんが、以下のコードを参考に自分で記述してください。
'use strict';
var IMAGE_DIR_PATH = "D:\\foobar2000\\MyButtonJScirpt\\";
function addMeta(tag, value) {
console.log("\naddMeta STARTED");
var handles = plman.GetPlaylistSelectedItems(plman.ActivePlaylist);
console.log(handles);
var arr = [];
for(var i=0; i<handles.Count; i++) {
console.log("Roop: " + i);
var info = handles[i].GetFileInfo();
var OldValue = info.MetaValue(info.MetaFind(tag), 0);
console.log("OldValue: " + OldValue);
var NewValue = OldValue;
if(OldValue.indexOf(value) != -1) {
console.log("Tag already has value");
} else {
NewValue = NewValue + " / " + value;
}
console.log("NewValue: " + NewValue);
arr.push({[tag] : NewValue});
}
var json = JSON.stringify(arr);
console.log("JSON: " + json);
handles.UpdateFileInfoFromJSON(json);
console.log("addMeta FINISHED");
}
window.DefineScript('Tag buttons', {author:'aresei-note.com', options:{grab_focus:false}});
include(fb.ComponentPath + 'samples\\complete\\js\\lodash.min.js');
include(fb.ComponentPath + 'samples\\complete\\js\\helpers.js');
include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');
let panel = new _panel(true);
let ButtonAddFolk = new _buttons();
let ButtonAddInstrumental = new _buttons();
let ButtonAddWithoutVocal = new _buttons();
ButtonAddFolk.buttons.menu = new _button(
5, 5, 50, 25,
{normal : IMAGE_DIR_PATH + "Folk.png"}
);
ButtonAddInstrumental.buttons.menu = new _button(
0, 40, 145, 25,
{normal : IMAGE_DIR_PATH + "Instrumental.png"}
);
ButtonAddWithoutVocal.buttons.menu = new _button(
0, 75, 150, 25,
{normal : IMAGE_DIR_PATH + "WithoutVocal.png"}
);
function on_paint(gr) {
panel.paint(gr);
ButtonAddFolk.paint(gr);
ButtonAddInstrumental.paint(gr);
ButtonAddWithoutVocal.paint(gr);
}
function on_mouse_move(x, y) {
ButtonAddFolk.move(x, y);
ButtonAddInstrumental.move(x, y);
ButtonAddWithoutVocal.move(x, y);
}
function on_mouse_leave() {
ButtonAddFolk.leave();
ButtonAddInstrumental.leave();
ButtonAddWithoutVocal.leave();
}
function on_mouse_lbtn_up(x, y, mask) {
if(ButtonAddFolk.buttons.menu.trace(x,y)) {
console.log("click folk button");
addMeta("genre", "Folk");
}
if(ButtonAddInstrumental.buttons.menu.trace(x,y)) {
console.log("click instrumental button");
addMeta("comment", "Instrumental");
}
if(ButtonAddWithoutVocal.buttons.menu.trace(x,y)) {
console.log("click without vocal button");
addMeta("comment", "WithoutVocal");
}
return true;
}
上記コードの実装時のサンプル画像です。
