I just sent this to someone in a PM who was asking about making a skin, but it seems I should post this for public consumption. This was fired off quickly and obviously needs to be fleshed out and expanded...
At this point, I have put my time into trying to finish the jukebox, so I have not written a skin builder. Fortunately, building a skin is not that hard. Things to remember:
- All coordinates and measurements are relative to the background image, not the actual resolution.
- Pixels in the background image are always assumed to be square; they will be corrected for the aspect ratio of the monitor, resolution and orientation at runtime to stay square.
Basic skins are very easy. Here, for example, is the classic.skn with the comments stripped out to make it shorter:
# Now Playing display
# Song List display
# Selection display
# Credit Display
That's it. It comes down to:
- Pick the background
- Set the selection method and range of selection keys
- Set the location, size, color, and number of lines of the displays (or disable them)
- Define the appearance of the titlestrips
- Define the size and location of one or more grid(s) of titlestrips
That is all there is to a basic skin. Where it gets more complicated is when you start adding icons that create or react to jukebox events; these icons are of course critical for touchscreen use. For this, we shift gears and look at default.skn. I'll skip all of the stuff covered above and go right to the icons:
[Icon1](This is just a subset of the 17 icons in default.skn, but the rest are like Icon4 and Icon5.)
Here we see the two different kinds of icons: non-clickable icons, which simply react to events, and clickable icons, which both create and react to events. Correspondingly, there are two kinds of events an icon can send or receive: BTN_ events, which act as if one of the buttons were pressed when sent, and MSG_ events, which report on the state of the jukebox. Clickable icons should always send BTN_ events; non-clickable icons can react to either BTN_ or MSG_ events. The BTN_ events are listed in controls.ini; the MSG_ events are listed in readme.txt.
BTN_ events always un-set themselves after 1/10th of a second, and MSG_ events un-set themselves when the condition is no longer true. A perfect example is to compare BTN_PAUSE vs. MSG_SONGPAUSED. When BTN_PAUSE is pressed, either on the keyboard or by clicking a clickable icon assigned to it, the BTN_PAUSE message is processed, which pauses the current song and pushes BTN_PAUSE and MSG_SONGPAUSED onto the message queue, and a -BTN_PAUSE (unset BTN_PAUSE) onto the timer queue. The user interface sees the BTN_PAUSE and causes whatever icons are assigned to it to display their OnImage, or if no OnImage is assigned it makes the OffImage (or the background if no OffImage is assigned) appear to be "pressed". The same thing happens with MSG_SONGPAUSED, so if you have an OffImage that looks like an unlit LED and an OnImage that looks like a lit LED, the LED for that icon will appear to "light" in response to MSG_SONGPAUSED. A tenth of a second later, -BTN_PAUSE is sent to the user interface, reverting any icons assigned to it back to their OffImage (or the background if no OffImage is assigned), but the song is still paused. When BTN_PAUSE is pressed again, the process repeats, except this time processing the message results in starting the song and sending BTN_PAUSE and -MSG_SONGPAUSED to the interface, and again -BTN_PAUSE to the timer queue. If the clickable icon instead was set to MSG_SONGPAUSED, nothing would happen, as the jukebox engine doesn't react to MSG_ messages, only BTN_ messages.
Hopefully that makes some sense!