Maybe I'm doing something wrong, but when I try to set just one button (var b_single=6), the panel stops working - no hover on images, no left-click menu, etc. (?) It works correctly with two or more buttons.
Thanks so much for the script though, looks extremely useful!
(I'm only testing in a default install by the way, not a theme/skin. JSP 3.4.10)
I'm using all buttons is single button mode. I just reloaded the code in the relevant button and I don't have issues with it.
It is the Playbackorder button. It is the only button that relies on a non standard foobar variable (plman.PlaybackOrder) which is as I remember correctly native for Marc's playlistmanager. BTW. He just released a 3.4.11.
My best guess that variable is not defined in your environment.
This is the code (which I cleanup up after 3.4.10 was released) I just loaded in button 6 and works fine in my CUI/PSS skin. Maybe try again?
// ==PREPROCESSOR==
// @name "Playback Buttons - Menu, Stop, Play/Pause, Previous, Next, PBO, ReplayGain, OutputDevice - All with rightbutton extras"
// @author "marc2003, modified by Defender"
// @import "%fb2k_component_path%helpers.txt"
// @import "%fb2k_component_path%samples\js\lodash.min.js"
// @import "%fb2k_component_path%samples\js\common.js"
// @import "%fb2k_component_path%samples\js\panel.js"
// ==/PREPROCESSOR==
// JSP3 3.4.10 2024-02-28. Supports transparency. Integrated Imagebutton code with the samples provided with this version
var b_single = 6; // 0= Select multiple buttons 1= Menu 2= Stop 3= Play/Pause 4= Previous 5= Next 6= PBO 7=ReplayGain 8= OutputDevice
var transparant = 1; // 0=OFF paint background - set desired colour in var colours below 1=ON do not paint background
if (b_single==0) {
// Select multiple buttons 0=OFF 1=ON. Make sure panel has enough width otherwise hover can stay activated with mouseovers
// Left click Right click
b_menu = 1; // Main Menu - Help Menu
b_stop = 1; // Stop - Stop After Current
b_play = 1; // Play/Pause - Random
b_prev = 1; // Previous - Seek Back 10 sec
b_next = 1; // Next - Seek Ahead 10 sec
b_pbo = 1; // PBO Dropdown - Reset to Default
b_rg = 1; // ReplayGain Dropdown - Reset to Track
b_out = 1; // OutputDevice Dropdown - Preferences
}
//////////////////////////////////////////////////////////////
if (b_single>0) {
// Set all buttons OFF
b_menu = 0;
b_stop = 0;
b_play = 0;
b_prev = 0;
b_next = 0;
b_pbo = 0;
b_rg = 0;
b_out = 0;
switch (b_single) {
case 1: b_menu = 1; break;
case 2: b_stop = 1; break;
case 3: b_play = 1; break;
case 4: b_prev = 1; break;
case 5: b_next = 1; break;
case 6: b_pbo = 1; break;
case 7: b_rg = 1; break;
case 8: b_out = 1; break;
}
}
var bc = b_menu + b_stop + b_play + b_prev + b_next + b_pbo + b_out + b_rg; // Number of active buttons
if (bc==0) {b_menu=1; bc=1} // Activate at least one button
var r_pbo_help = 0; // 0=OFF rightclick resets to PBO Default 1=ON rightclick shows help menu
var r_rg_help = 0; // 0=OFF rightclick resets to ReplayGain Track 1=ON rightclick shows help menu
var mx = 0; // Placeholder for x of dropdown - Menu
var my = 0; // Placeholder for y of dropdown - Menu
var px = 0; // Placeholder for x of dropdown - PBO
var py = 0; // Placeholder for y of dropdown - PBO
var rx = 0; // Placeholder for x of dropdown - ReplayGain
var ry = 0; // Placeholder for y of dropdown - ReplayGain
var ox = 0; // Placeholder for x of dropdown - OutputDevice
var oy = 0; // Placeholder for y of dropdown - OutputDevice
var colours = {
background : RGB(192, 192, 192),
// normal : RGB( 63, 100, 126),
// hover : RGB(192, 224, 255),
// paused : RGB(144, 177, 201),
// sac_normal : RGB(125, 64, 65),
// sac_hover : RGB(196, 30, 35),
};
var configPath = fb.ProfilePath + 'cui-configs\\Defender\\';
var imgPath = configPath + 'Images\\PlayBack\\';
var img_menu_normal = utils.LoadImage(imgPath + 'Menu-normal.png');
var img_menu_hover = utils.LoadImage(imgPath + 'Menu-hover.png');
var img_play_normal = utils.LoadImage(imgPath + 'Play-normal.png');
var img_play_hover = utils.LoadImage(imgPath + 'Play-hover.png');
var img_pause_normal = utils.LoadImage(imgPath + 'Pause-normal.png');
var img_pause_hover = utils.LoadImage(imgPath + 'Pause-hover.png');
var img_pause_paused = utils.LoadImage(imgPath + 'Pause-paused.png');
var img_stop_normal = utils.LoadImage(imgPath + 'Stop-normal.png');
var img_stop_hover = utils.LoadImage(imgPath + 'Stop-hover.png');
var img_stopac_normal = utils.LoadImage(imgPath + 'StopAC-normal.png');
var img_stopac_hover = utils.LoadImage(imgPath + 'StopAC-hover.png');
var img_prev_normal = utils.LoadImage(imgPath + 'Prev-normal.png');
var img_prev_hover = utils.LoadImage(imgPath + 'Prev-hover.png');
var img_next_normal = utils.LoadImage(imgPath + 'Next-normal.png');
var img_next_hover = utils.LoadImage(imgPath + 'Next-hover.png');
var img_out_normal = utils.LoadImage(imgPath + 'OutputDevice-normal.png');
var img_out_hover = utils.LoadImage(imgPath + 'OutputDevice-hover.png');
var pbo_imgname = ['Default', 'RepeatPlaylist', 'RepeatTrack', 'Random', 'ShuffleTracks', 'ShuffleAlbums', 'ShuffleFolders' ];
var rg_imgname = ['Disable', 'Track', 'Album', 'PBO' ];
//////////////////////////////////////////////////////////////
var panel = new _panel();
var buttons = new _buttons();
var bs = _scale(24);
buttons.update = function () {
/* ORIGINAL
var x = ((panel.w - bs * 4) / 2);
var y = Math.round((panel.h - bs) / 2);
this.buttons.stop = new _button(x, y, bs, bs, { char : chars.stop, colour:fb.StopAfterCurrent ? colours.sac : colours.buttons}, null, function () { fb.Stop(); }, 'Stop');
this.buttons.previous = new _button(x + bs, y, bs, bs, { char : chars.prev, colour:colours.buttons }, null, function () { fb.Prev(); }, 'Previous');
this.buttons.play = new _button(x + (bs * 2), y, bs, bs, { char : !fb.IsPlaying || fb.IsPaused ? chars.play : chars.pause, colour:colours.buttons}, null, function () { fb.PlayOrPause(); }, !fb.IsPlaying || fb.IsPaused ? 'Play' : 'Pause');
this.buttons.next = new _button(x + (bs * 3), y, bs, bs, { char : chars.next, colour:colours.buttons }, null, function () { fb.Next(); }, 'Next');
*/
var h = Math.round( panel.h * 100 / 100);
var y = Math.round((panel.h - h) / 2);
var w_menu = b_menu * Math.round(h); // Button width needed - Menu
var w_stop = b_stop * Math.round(h); // Button width needed - Stop
var w_play = b_play * Math.round(h); // Button width needed - Play/Pause
var w_prev = b_prev * Math.round(h); // Button width needed - Previous
var w_next = b_next * Math.round(h); // Button width needed - Next
var w_pbo = b_pbo * Math.round(h); // Button width needed - PBO
var w_rg = b_rg * Math.round(h); // Button width needed - ReplayGain
var w_out = b_out * Math.round(h); // Button width needed - OutputDevice
if (bc>0) {
var w_bp = Math.round((panel.w - w_menu - w_stop - w_play - w_prev - w_next - w_pbo - w_rg - w_out) / (bc-1)); // Padding between buttons
var x = (panel.w - w_menu - w_stop - w_play - w_prev - w_next - w_pbo - w_rg - w_out - w_bp*(bc-1)) / 2; // Half of remainder of panel.w minus used width for buttons and padding in between buttons. No padding left of first and right of last
}
var img_pbo_normal = utils.LoadImage(imgPath + 'PBO-' + pbo_imgname[plman.PlaybackOrder] + '-normal.png');
var img_pbo_hover = utils.LoadImage(imgPath + 'PBO-' + pbo_imgname[plman.PlaybackOrder] + '-hover.png');
var img_rg_normal = utils.LoadImage(imgPath + 'RG-' + rg_imgname[fb.ReplaygainMode] + '-normal.png');
var img_rg_hover = utils.LoadImage(imgPath + 'RG-' + rg_imgname[fb.ReplaygainMode] + '-hover.png');
if ( fb.IsPlaying ) { img_pp_normal = img_pause_normal; img_pp_hover = img_pause_hover }
if ( fb.IsPaused ) { img_pp_normal = img_pause_paused; img_pp_hover = img_play_hover }
if ( !fb.IsPlaying ) { img_pp_normal = img_play_normal; img_pp_hover = img_play_hover }
// CREATE BUTTONS
w = x-w_bp; // Initialize to avoid left padding on first button in case of more than one button defined
x = x+w+(b_menu*w_bp); w=w_menu; if (bc==1) {x=(panel.w-w)/2;}
mx = x - _scale(28); my = panel.h + _scale(3);
this.buttons.menu = new _button_img(x, y, w, h, img_menu_normal, img_menu_hover, function () { _menu(mx, my); }, '');
x = x+w+(b_stop*w_bp); w=w_stop; if (bc==1) {x=(panel.w-w)/2;}
this.buttons.stop = new _button_img(x, y, w, h, fb.StopAfterCurrent ? img_stopac_normal : img_stop_normal, fb.StopAfterCurrent ? img_stopac_hover : img_stop_hover, function () { fb.Stop(); }, '');
x = x+w+(b_play*w_bp); w=w_play; if (bc==1) {x=(panel.w-w)/2;}
this.buttons.play = new _button_img(x, y, w, h, img_pp_normal, img_pp_hover, function () { fb.PlayOrPause(); }, !fb.IsPlaying || fb.IsPaused ? '' : '');
x = x+w+(b_prev*w_bp); w=w_prev; if (bc==1) {x=(panel.w-w)/2;}
this.buttons.prev = new _button_img(x, y, w, h, img_prev_normal, img_prev_hover, function () { fb.Prev(); }, '');
x = x+w+(b_next*w_bp); w=w_next; if (bc==1) {x=(panel.w-w)/2;}
this.buttons.next = new _button_img(x, y, w, h, img_next_normal, img_next_hover, function () { fb.Next(); }, '');
x = x+w+(b_pbo*w_bp); w=w_pbo; if (bc==1) {x=(panel.w-w)/2;}
px = x - _scale(28); py = panel.h + _scale(3);
this.buttons.pbo = new _button_img(x, y, w, h, img_pbo_normal, img_pbo_hover, function (x, y, mask) { _pbo(px, py);}, '');
x = x+w+(b_rg*w_bp); w=w_rg; if (bc==1) {x=(panel.w-w)/2;}
rx = x - _scale(28); ry = panel.h + _scale(3);
this.buttons.rg = new _button_img(x, y, w, h, img_rg_normal, img_rg_hover, function (x, y, mask) { _rg(rx, ry);}, '');
x = x+w+(b_out*w_bp); w=w_out; if (bc==1) {x=(panel.w-w)/2;}
ox = x - _scale(28); oy = panel.h + _scale(3);
this.buttons.out = new _button_img(x, y, w, h, img_out_normal, img_out_hover, function () { _out(ox, oy);}, '');
}
function _button_img(x, y, w, h, normal, hover, fn, tiptext) {
this.paint = function (gr) {
if (this.current) {
gr.DrawImage(this.current, this.x, this.y, this.w, this.h, 0, 0, this.current.Width, this.current.Height)
// _drawImage(gr, this.current, this.x, this.y, this.w, this.h)
}
}
this.containsXY = function (x, y) {
return x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h;
}
this.lbtn_up = function (x, y, mask) {
if (this.fn) {
this.fn(x, y, mask);
}
}
this.cs = function (s) {
if (s == 'hover') {
this.current = this.hover;
_tt(this.tiptext);
} else {
this.current = this.normal;
}
window.RepaintRect(this.x, this.y, this.w, this.h);
}
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.fn = fn;
this.tiptext = tiptext;
this.normal = normal;
this.hover = hover || normal;
this.current = normal;
}
function _pbo(x, y, flags) {
var menu = window.CreatePopupMenu();
var arr = new Array("Default", "Repeat (Playlist)", "Repeat (Track)", "Random", "Shuffle (tracks)", "Shuffle (albums)", "Shuffle (folders)");
var active = -1;
for (var i = 0; i < arr.length; i++) {
menu.AppendMenuItem(MF_STRING, i + 1, arr[i]);
if (arr[i].active) active = i;
}
menu.CheckMenuRadioItem(1, arr.length + 1, plman.PlaybackOrder + 1);
var idx = menu.TrackPopupMenu(x, y);
menu.Dispose();
if (idx > 0) {fb.RunMainMenuCommand("Playback/Order/" + arr[idx - 1]); };
}
function _rg(x, y, flags) {
var menu = window.CreatePopupMenu();
var arr = new Array("Disable", "Set to Track", "Set to Album", "Set to Track/Album by playback order");
var active = -1;
for (var i = 0; i < arr.length; i++) {
menu.AppendMenuItem(MF_STRING, i + 1, arr[i]);
if (arr[i].active) active = i;
}
menu.CheckMenuRadioItem(1, arr.length + 1, fb.ReplaygainMode + 1);
var idx = menu.TrackPopupMenu(x, y);
menu.Dispose();
if (idx > 0) {fb.ReplaygainMode = idx - 1; };
}
function _out(x, y) {
var menu = window.CreatePopupMenu();
var str = fb.GetOutputDevices();
var arr = JSON.parse(str);
var active = -1;
for (var i = 0; i < arr.length; i++) {
menu.AppendMenuItem(MF_STRING, i + 1, arr[i].name);
if (arr[i].active) active = i;
}
if (active > -1) menu.CheckMenuRadioItem(1, arr.length + 1, active + 1);
var idx = menu.TrackPopupMenu(x, y);
menu.Dispose();
if (idx > 0) fb.RunMainMenuCommand('Playback/Device/' + arr[idx - 1].name);
}
function on_playback_order_changed(new_index) {
buttons.update();
window.Repaint();
}
function on_replaygain_mode_changed(new_mode) {
buttons.update();
window.Repaint();
}
function on_mouse_lbtn_up(x, y) {
buttons.lbtn_up(x, y);
}
function on_mouse_leave() {
buttons.leave();
}
function on_mouse_move(x, y) {
buttons.move(x, y);
}
function on_mouse_rbtn_up(x, y) {
if (buttons.buttons.menu.containsXY(x, y)) {
_help(mx, my);
return true;
}
if (buttons.buttons.stop.containsXY(x, y)) {
fb.StopAfterCurrent = !fb.StopAfterCurrent;
return true;
}
if (buttons.buttons.play.containsXY(x, y)) {
fb.Random(); // Select and play Random track immediately
return true;
}
if (buttons.buttons.prev.containsXY(x, y)) {
fb.RunMainMenuCommand('Playback/Seek/Back by 10 seconds');
return true;
}
if (buttons.buttons.next.containsXY(x, y)) {
fb.RunMainMenuCommand('Playback/Seek/Ahead by 10 seconds');
return true;
}
if (buttons.buttons.pbo.containsXY(x, y)) {
if (r_pbo_help == 1) {
_help(px, py);
return true;
}
// Cycle through options
// if ( plman.PlaybackOrder == 6 ) plman.PlaybackOrder = 0;
// else plman.PlaybackOrder = plman.PlayBackOrder + 1;
// Reset to Default
plman.PlaybackOrder = 0;
return true;
}
if (buttons.buttons.rg.containsXY(x, y)) {
if (r_rg_help == 1) {
_help(rx, ry);
return true;
}
// Reset to Track
fb.ReplaygainMode = 1;
return true;
}
if (buttons.buttons.out.containsXY(x, y)) {
fb.RunMainMenuCommand('File/Preferences');
return true;
}
return panel.rbtn_up(x, y);
}
function on_paint(gr) {
if (transparant == 0){
gr.Clear(colours.background);
}
buttons.paint(gr);
}
function on_playback_pause() {
buttons.update();
window.Repaint();
}
function on_playback_starting() {
buttons.update();
window.Repaint();
}
function on_playback_stop() {
buttons.update();
window.Repaint();
}
function on_playlist_stop_after_current_changed() {
buttons.update();
window.Repaint();
}
function on_size() {
panel.size();
buttons.update();
}