Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Custom "like" button (anywhere) (Read 2540 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Custom "like" button (anywhere)

Hi,
What would be the up-to-date way to create a simple customizable "like" button that could be located anywhere on the layout ? (not necessarily on the toolbar).
The button action would be linked to a simple Masstagger script that would add or remove a value to a given tag field of the selected track.
The button itself could be a user-defined image (e.g. a heart). Two images actually, related to the selected track : grey heart = default, and read heart = "like".
Are there already some SMP/JSP scripts for this ? Or maybe another way ?
Thanks.
PS : I'm using DUI.

Re: Custom "like" button (anywhere)

Reply #1
You could try the Panel Stack Splitter $textbutton function with a thumb up character. I used to have a button like that in my PSS layout.
I'm late

Re: Custom "like" button (anywhere)

Reply #2
Thanks, but I guess that's a very old solution and it's not customizable enough for my taste (no pictures).
I'm looking for something more up-to-date, hence the SMP/JSP reference.
I know up-to-date solutions already exist as I've seen them in many layouts. I'm just asking how it's done.

Re: Custom "like" button (anywhere)

Reply #3
PSS also provides an $imagebutton function for that matter, but you don't actually need pictures to achieve what you are asking for, you're better off with a heart icon character which can be drawn in any colour you want by code. This applies to both PSS and javascript host panels.
I'm late

Re: Custom "like" button (anywhere)

Reply #4
Excuse me, I understand that PSS works, but... am I free to decide what I want here ? Thank you.
I am used to SMP/JSP, so if there is a SMP/JSP solution (which I'm pretty sure there is), I will favor it.
If there's nothing else, I will use PSS, but I'm sure there are other solutions.

Re: Custom "like" button (anywhere)

Reply #5
Excuse me, I understand that PSS works, but... am I free to decide what I want here ? Thank you.
Of course you are, my previous post was not insisting on using PSS, but rather on using an icon character instead of pictures. As I said above, this would be the best way (and more "updated" as to your likes) to work with SMP or JSP as well.


I am used to SMP/JSP, so if there is a SMP/JSP solution (which I'm pretty sure there is), I will favor it.
If there's nothing else, I will use PSS, but I'm sure there are other solutions.
Javascript host panels are definitely the best and most customizable solution, given you know how to code, which I guess is not the case, since you are asking, and this is the only reason why I suggested you PSS. A "like" button in itself can be pretty simple to code; for my part I replaced most of my PSS stuff with SMP scripts, but my "like" button derives from an inheritance chain which is coded in various scripts. It's a system that makes sense in my configuration, but is way too overkill for a standalone "like" button.
If what you are looking for is a ready-made script, with all required features customizable via user interface (property window or custom context menus) in order to fit it in your set up, I think it's unlikely you will find it.
If you really want to use SMP you should consider writing your own code. I'm willing to help, if you provide enough information on the usage context.


I'm late


Re: Custom "like" button (anywhere)

Reply #7
Here's a draft to start with. This "Like" button targets the selected tracks, or the playing track  if the selection viewer is set to prefer the currently playing track. It runs a quicktag command, setting the rating field to 5 for liked tracks and deleting it for unliked tracks. All these functionalities can be adjusted to your set up if you provide more details.

Code: [Select]
"use strict";
include(fb.ComponentPath + "//docs//Helpers.js");
include(fb.ComponentPath + "//docs//Flags.js");


let likeButton = new LikeButton();


function on_paint(gr){
    likeButton.paint(gr);
}


function on_mouse_move(x, y){
    likeButton.mouse_move(x, y);
}


function on_mouse_leave(){
    likeButton.mouse_leave();
}


function on_mouse_lbtn_up(){
    likeButton.mouse_lbtn_up();
}


function on_metadb_changed(){
    window.Repaint();
}


function on_selection_changed(){
    window.Repaint();
}


function LikeButton(){
    this.font = gdi.Font(window.GetProperty("FONT", "segoe UI"), window.GetProperty("FONT_SIZE", 48));
    this.label = String.fromCharCode(9829);
    this.paint = (gr) => {
        this.forecolour = this.active?colours.Red:colours.Gray;       
        gr.GdiDrawText(this.label, this.font, this.forecolour, 0, 0, window.Width, window.Height, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        if (this.mouseover && (this.target.Count > 0)) gr.FillSolidRect(0, 0, window.Width, window.Height, setAlpha(colours.Gray, 60));
    }
    this.mouse_move = (x, y) => {
        if (!this.mouseover){
            this.mouseover = true;
            window.Repaint();
        }
    }
    this.mouse_leave = () => {
        this.mouseover = false;
        window.Repaint();
    }
    this.mouse_lbtn_up = () => {
        fb.RunContextCommandWithMetadb(this.command, this.target);
    }
    this.mouseover = false;
}


Object.defineProperty(LikeButton.prototype, "target", {get: () => fb.GetSelections()})
Object.defineProperty(LikeButton.prototype, "active", {get: function(){return Math.min(...fb.TitleFormat("%rating%").EvalWithMetadbs(this.target)) == 5}})
Object.defineProperty(LikeButton.prototype, "command", {get: function(){return "Tagging/Quick Tagger/Set <rating> to/" + (this.active?"[Remove Field]":"5")}});
I'm late

Re: Custom "like" button (anywhere)

Reply #8
Thanks for these new replies.
I'm not a coder, but SMP/JSP come with a bunch of scripts that one can eventually customize. I'm currently using some of them by WilB, TheQwertiest or marc2003. I'm surprised that there isn't already a script for that.

Thanks for the draft. :) I have tried it, but so far I can't make it work.
It seems to run nicely in a SMP panel, and it displays a grey heart, which is a good sign.
However, clicking on it does nothing, and the tagging does not take place.
I have checked, and I have both Helpers.js and Flags.js at the right locations.
Maybe it's the "Tagging/Quick Tagger/Set <rating> to/" part ? I don't know about Quick Tagger. I'm using Masstagger, and all my scripts are under Tagging/Scripts/

Re: Custom "like" button (anywhere)

Reply #9
Thanks for the draft. :) I have tried it, but so far I can't make it work.
It seems to run nicely in a SMP panel, and it displays a grey heart, which is a good sign.
However, clicking on it does nothing, and the tagging does not take place.
I have checked, and I have both Helpers.js and Flags.js at the right locations.
Maybe it's the "Tagging/Quick Tagger/Set <rating> to/" part ? I don't know about Quick Tagger. I'm using Masstagger, and all my scripts are under Tagging/Scripts/

Yes, it requires a quicktag plugin installed and an action that sets the rating tag to 5, but that is just an example, we can adjust it to your set up. You said you want to update the tags with masstagger, if I understand correctly. Can you tell me a bit more? What is the name of the masstagger script you want to execute with the like button and what does it do?
I'm late

Re: Custom "like" button (anywhere)

Reply #10
BTW, I wrote the script to run a context command because you said you want to use the masstagger plugin to update tags, but you don't actually need an extra plugin for that (nor masstagger, neither quicktag). This version of the script updates tags by code. I commented out the lines I replaced for you to see the changes. As the previous version, this one writes the value 5 in the rating field for liked tracks.

Code: [Select]
"use strict";
include(fb.ComponentPath + "//docs//Helpers.js");
include(fb.ComponentPath + "//docs//Flags.js");


let likeButton = new LikeButton();


function on_paint(gr){
    likeButton.paint(gr);
}


function on_mouse_move(x, y){
    likeButton.mouse_move(x, y);
}


function on_mouse_leave(){
    likeButton.mouse_leave();
}


function on_mouse_lbtn_up(){
    likeButton.mouse_lbtn_up();
}


function on_metadb_changed(){
    window.Repaint();
}


function on_selection_changed(){
    window.Repaint();
}


function LikeButton(){
    this.font = gdi.Font(window.GetProperty("FONT", "segoe UI"), window.GetProperty("FONT_SIZE", 48));
    this.label = String.fromCharCode(9829);
    this.paint = (gr) => {
        this.forecolour = this.active?colours.Red:colours.Gray;       
        gr.GdiDrawText(this.label, this.font, this.forecolour, 0, 0, window.Width, window.Height, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        if (this.mouseover && (this.target.Count > 0)) gr.FillSolidRect(0, 0, window.Width, window.Height, setAlpha(colours.Gray, 60));
    }
    this.mouse_move = (x, y) => {
        if (!this.mouseover){
            this.mouseover = true;
            window.Repaint();
        }
    }
    this.mouse_leave = () => {
        this.mouseover = false;
        window.Repaint();
    }
    this.mouse_lbtn_up = () => {
//      fb.RunContextCommandWithMetadb(this.command, this.target);
        this.updateTags();
    }
    this.mouseover = false;
}


Object.defineProperty(LikeButton.prototype, "target", {get: () => fb.GetSelections()})
Object.defineProperty(LikeButton.prototype, "active", {get: function(){return Math.min(...fb.TitleFormat("%rating%").EvalWithMetadbs(this.target)) == 5}})
//Object.defineProperty(LikeButton.prototype, "command", {get: function(){return "Tagging/Quick Tagger/Set <rating> to/" + (this.active?"[Remove Field]":"5")}});
Object.defineProperty(LikeButton.prototype, "updateTags", {value: function(){
    let arr = [];
    for (let i = 0; i < this.target.Count; ++i) {arr.push({"rating" : this.active?"":5})};
    this.target.UpdateFileInfoFromJSON(JSON.stringify(arr));
    }
})

Mind that it can target multiple tracks. When you select more than one track, it will behave as if the tracks were all unliked if at least one of them is, that means the icon will be painted gray and clicking on it will like all the selected tracks.
I'm late

Re: Custom "like" button (anywhere)

Reply #11
That actually works perfectly ! :D Impressive. I didn't know that you could update tags by code. It makes things even easier here. Yes, I said I'd like to use the Masstagger because I didn't even know it was possible to do otherwise. Sorry about that.

I have three questions :
  • Is there a way to adjust the heart's color [EDIT - and background color] more precisely than by color names ? I've tried "violet" instead of red but it gives some pinkish color. I wish I could add a more precise color code like #9900ff or #6600cc.
    (see attached picture : this is how the panel currently looks on my UI, as you can see the background is darker)
    I've seen that the "Properties" of the panel allow you to adjust the font size, and I think the script would be perfect with a second / third property for the font color / background color.
  • Is there a way to link this SMP script to a keyboard shortcut ?
  • As a security protection, I'd like to actually be UNABLE to tag more than one track at a time. For example in Advanced properties, my Masstagger is configured to warn me before updating more than 1 item. But if that's too complicated, nevermind.

Thanks.

Re: Custom "like" button (anywhere)

Reply #12
  • Is there a way to adjust the heart's color [EDIT - and background color] more precisely than by color names ? I've tried "violet" instead of red but it gives some pinkish color. I wish I could add a more precise color code like #9900ff or #6600cc.
    (see attached picture : this is how the panel currently looks on my UI, as you can see the background is darker)
    I've seen that the "Properties" of the panel allow you to adjust the font size, and I think the script would be perfect with a second / third property for the font color / background color.
You can check the hexadecimal value of all the pre-calculated colours in the Helpers.js document. Anyway I've added new properties to edit all colours:
ON_COLOUR is the forecolour when the track is liked;
OFF_COLOUR is the forecolour when the track is unliked;
HOT_COLOUR is the backgrund colour when the mouse hovers over the button.

I made them so that you can enter RGB or RGBA coordinates (the alpha value is optional, but recommended for the HOT_COLOUR, of course).


  • Is there a way to link this SMP script to a keyboard shortcut ?
Yes, the tag update action is now bound to the main menu command "File / Spider Monkey Panel / 1". If option number 1 is already used by other scripts, you can change this value in the window properties, too.


  • As a security protection, I'd like to actually be UNABLE to tag more than one track at a time. For example in Advanced properties, my Masstagger is configured to warn me before updating more than 1 item. But if that's too complicated, nevermind.
I think a warning dialog window is possible with utils.ShowHtmlDialog() but I never used it, plus I'm not familiar with HTML. I might check it out, but it will take time. However, limiting the script to update only one track at a time is not a problem, but I need to understand better how you want to use it. Which track should I target? The script now targets the tracks from the selection viewer (the ones read by the selection properties panel). How should it behave when multiple tracks are actually selected?
I'm late

Re: Custom "like" button (anywhere)

Reply #13
Thanks, that's really great. I appreciate your help, sorry if I seemed a bit rude at first, it wasn't my intention at all. :)

There is only one thing that still bothers me : if you look at my previous picture, you'll see that the default background color (when the mouse does NOT hover) is darker than the surrounding components. I'd like it to be the same (53,53,53). I don't know why it's darker. In Preferences > Colors and Fonts, the background color is indeed 53,53,53.

As for my use, it's very straightforward : I'm listening to a track (or I'm selecting a single track), and I decide that I like it, so I click on the button. So the script should always target the currently selected track, whether it's playing or not. In case of multiple selected tracks, the script should just do nothing (or show a warning). If I want to tag multiple tracks I'll just use Masstagger, not a single-click button, for security reasons. ;)

Re: Custom "like" button (anywhere)

Reply #14
I see, I forgot that you are using DUI. I'm used to work with Columns UI which allows pseudo-transparency, so the background colour you see does not actually come from the script.
I added a background now, which takes the colour from the UI settings.
I also edited the script so that the update tags action takes place when only one track is selected. You will know that it is disabled because the background colour won't change on mouseover if no track or more than one track is selected.
if you want the script to always target the selected track, even when foobar2000 is playing, though, you have to make sure the Display/Selection Viewer option "Prefer current selection" is checked. Anyway you can always see in the Selection Properties panel what the active selection is.
I'm late

Re: Custom "like" button (anywhere)

Reply #15
Well, that's just amazing. I guess I couldn't ask for more.
I have just tested it, and it works perfectly the way I imagined it.
You, Sir @davideleo , have all my thanks and all my respect.


Re: Custom "like" button (anywhere)

Reply #16
Oh, just one thing :

Yes, the tag update action is now bound to the main menu command "File / Spider Monkey Panel / 1". If option number 1 is already used by other scripts, you can change this value in the window properties, too.
I don't see that name/value in the Properties, there are only 5 lines : font, font size, hot/on/off colour.


Re: Custom "like" button (anywhere)

Reply #18
Ah, we are so close ! Now we have the 6 expected properties, but we have lost the default background.  :D

Re: Custom "like" button (anywhere)

Reply #19
Oops, I updated the wrong version :D
I'm late

Re: Custom "like" button (anywhere)

Reply #20
Thanks, I like it. :)
Quis custodiet ipsos custodes?  ;~)

 

Re: Custom "like" button (anywhere)

Reply #21
Works perfectly now, including the keyboard shortcut :D
Plus you've made many people happy, judging by the number of downloads ;)