Author Topic: Skin creation tutorial  (Read 15456 times)

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Skin creation tutorial
« on: October 29, 2008, 09:00:30 PM »
This tutorial was originally a set of replies in the "Skin creation overview" topic.  The tutorial skin described here is included with recent versions of DWJukebox in the skins/tutorial folder

So let's talk about creating a new skin.

A new skin should have places for the following:

  • Displays: Two large ones (Now Playing and Coming Up) and two small ones (Credits and Selection).
  • Title strips: The number of strips depends on the control system and resolution you are targeting.  For example, using an ABCD 1234 arrangement limits you to 16 selections, whereas a 12345678 arrangement gives you up to 64 selections (8x8).
  • Buttons: Buttons are only necessary if you are planning to do a touch screen or mouse control.  If you are purely using mechanical buttons you do not need onscreen buttons.
  • Indicators: Any status indicators you want such as radio mode, credits available, invalid entry, etc.  Any MSG_ message supported by DWJukebox may be used to control an indicator; see the documentation for a full list.  Note that as far as the skin is concerned, the only difference between an indicator and a button is that an indicator is not clickable.

There are two ways to do buttons: One is to draw them onto your background; this is easier but less flexible.  The other is to make each button an image and to just leave blank space for those buttons; this is harder but more flexible as buttons can be rearranged or substituted very easily.

For the titlestrips of a singles-style jukebox, you also need to add the address of the song onto the background image.  In a later version I plan to have a way for the jukebox to do this for you, but for now you have to plan ahead and draw the addresses on.  Which strip gets which address?  Well, that depends on how we set up the titlestrips.

(Continued next post)

« Last Edit: February 25, 2010, 09:45:09 AM by Chris »

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Skin creation tutorial
« Reply #1 on: October 29, 2008, 10:16:27 PM »
First, we need to decide where to put our skin.  Most of the skins that ship with DWJukebox have their skin files residing in the Skins folder, with their component elements split into the Bgrounds, Icons, Labels, and Fonts folders.  You do not need to do this; in fact it is best if you don't.  The default skins are set up this way because they share many common elements.  Your skin will most likely either re-use some of these elements or use elements unique to that skin.  So I recommend that you create a folder in the skins folder to hold your skin file and all of the elements for that skin.  This will make it easier to share your skin.  Inside this folder, create a plain text file with the same name as the folder and an .skn extension.  (Note that if you use Notepad, it may add a .txt after your extension; if it does, rename the file to remove the extension.)

Go ahad and do that now.  Create a folder in the skins folder called mytut and an empty plain text file inside that folder called mytut.skn

Now we need a backdrop image.  Although many image formats are supported, you will most likely use a .JPG, .BMP, or (as of version 3.4.0) .PNG image. I took some button elements created for an unfinished skin by Gamecreature from the Build Your Own Arcade Controls forum and threw together a quick and dirty background.  We'll use this image for the tutorial.  Either copy that image from the skins/tutorial folder to your new mytut folder, or download it to your new mytut folder from this post.
« Last Edit: February 25, 2010, 09:56:29 AM by Chris »

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Skin creation tutorial
« Reply #2 on: October 29, 2008, 11:23:34 PM »
Now we have our background and our blank skin file.  Edit mytut.skn with your favorite text editor and let's create the skin file.

Skin files, along with all other configuration files used by DWJukebox, are in the format that many Windows configuration files use, the INI format. The file is divided into sections, with each section starting with the section name in square braces.

(NOTE: One difference between the DWJukebox INI format and the Windows format is that the DWJukebox format uses a pound sign (#) to denote a comment in the file instead of a semicolon.)

The first section we will define is the [Skin] section, which defines basic information about the skin, the most important of which is the background image:

Code: [Select]
[skin]
Author = Chris La Mantia
Description = Simple tutorial skin
background = tutorial.jpg

The Author and Description line don't do anything; eventually if I ever create a skin editor or skin browser this information will be used so it's good to add it.

Now let's define some fonts.  Older skins have a single font definition but DWJukebox supports a whole Fonts section for specifying each font individually, so let's use that:

Code: [Select]
[Fonts]
TitleFont = bluehigh.ttf
TitleFontSize = 26
TitleFontCondensed = bluecond.ttf
TitleFontCondensedSize = 24
TitleFontColor = Black
TitleFontCase = Normal
TitleFontAddQuotes = True
TitleFontQuoteSymbol = "

ArtistFont = bluehigh.ttf
ArtistFontSize = 22
ArtistFontCondensed = bluecond.ttf
ArtistFontCondensedSize = 18
ArtistFontColor = Black
ArtistFontCase = Uppercase
ArtistFontAddQuotes = False

FixedFont=jbdotmat.fnt

The individual elements of this section should be fairly self-explanatory.  The Condensed fonts are used when the text is too large to fit in the titlestrip area.  The Color can be expressed as either a standard X11/HTML color name (see the color chart in the documentation) or as an HTML RGB hexadecimal code such as #FF0000 for red or #000000 for black. (Three digit shortcuts such as #000 are not supported.)

The FixedFont is the dot-matrix font used for the displays, which do not yet support TrueType.  Fixed fonts date back to the oldest versions of DWJukebox; they are in a custom format.  There are five fixed fonts provided:

  • jbtotmat.fnt - The default dot-matrix font.
  • jblcd.fnt - A segmented, slanted, LCD-style font.
  • jbsans.fnt - A sans-serif font, similar to the Arial font in Windows.
  • jbsansb.fnt - A bold sans-serif font, similar to the Arial Bold font in Windows.
  • jbblack.fnt - A heavy, bold, sans-serif font, similar to the Arial Black font in Windows.

A size and color is not specified for the fixed font because these are specified in the displays. Speaking of displays, let's create some.

DWJukebox supports up to five displays; you can choose to include or exclude any of them.  The displays are numbered as follows:

  • Display1 - The Now Playing display.  Supports up to 5 lines of information.
  • Display2 - The Song List/Most Popular display.  Supports up to 5 lines of information.
  • Display3 - The Selection display.  Supports a single line; displays 1 to 7 digits for the currently entered selection, depending on the selection method.
  • Display4 - The Credits display.  Supports a single line; displays 2 digits for the current number of available credits.  Always displays 01 if RequireCredits is disabled.
  • Display5 - The Album Cover.  This is a graphic display rather than a text display; it shows an image of the album cover of the currently playing song.

First we'll build the Now Playing display:

[/list]
Code: [Select]
[Display1]
enabled=True
fontcase=UpperCase
x=22
y=20
w=490
h=144
lines=5
color=palegreen
bgcolor=transparent

Again, these should be fairly self-explanatory.  If Enabled is set to False, none of the other information is necessary.

There are a couple of things that bear explaining here.  First, for displays, the font size is not set directly; instead, the number of lines the display is to show is selected and the jukebox uses the largest size that will fit.  The Now Playing display (Display1) will never show more than 5 lines of information, and the Selection and Credits displays (Display3 and Display4) will never show more than one line.

The other thing worth noting is that bgcolor has a special color name called "transparent" which just draws the text directly on the background image.  This setting is currently the only one that supports "transparent" as a color name.

You can see here the coordinates and size of the display.  Where do these numbers come from?  They are pixels, relative to the background image.  The way I get these number is that I draw a temporary rectangle on the background image, and my graphic software shows me the X, Y, width, and height of that rectangle.

Let's fill in the other displays:

Code: [Select]
[Display2]
# Song List display
enabled=True
fontcase=UpperCase
x=527
y=20
w=486
h=144
lines=6
color=palegreen
bgcolor=transparent

[Display3]
# Selection display
enabled=True
x=837
y=691
w=69
h=48
color=palegreen
bgcolor=transparent

[Display4]
# Credit Display
enabled=True
x=923
y=691
w=57
h=40
color=palegreen
bgcolor=transparent

(Continued next post)


« Last Edit: February 25, 2010, 10:24:03 AM by Chris »

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Skin creation tutorial
« Reply #3 on: October 29, 2008, 11:44:49 PM »
Now it's time to define how songs are selected.  This is actually one of the most important decisions you will make, as it defines the number and type of buttons that will be needed onscreen or on the physical control panel.

Code: [Select]
[Selection]
SelectionMethod=Numeric
UseZero=False
HighNumber=8

This is a fairly simple skin, so the selection definition is simple: we are using an 8-digit keypad with no zero.  Selection patterns can be more complicated, though.  Let's say we have a juke that has numbers 0 through 5 and lettera A through Q, but does not have an I or an O.  (This was  common to avoid confusion between I and 1 and O and 0.)  This would be set up as:

Code: [Select]
[Selection]
SelectionMethod=AlphaNumeric
UseZero=True
HighNumber=5
HighLetter=Q
SkipLetterI=True
SkipLetterO=True

Next, we define what the titlestrips look like.  We'll use one of the included titlestrips for this rather than using a custom one to keep things simple.

Code: [Select]
[TitleStrips]
Background=jb45lb09.jpg
Width=297
Height=109
SongsPerStrip=Double
StripCount=12
FontSmoothing=true
FontFocusColor=Navy
FocusColor=MediumBlue
ShadowColor=Black
Animation=SlideHorizontal
Background is the image used for the titlestrip; it will be stretched and scaled to fit the Width and Height.

SongsPerStrip defines the type of strip:  Single or 1 will have a single selection with the title on top and artist on the bottom.  Double or 2 is a "classic" strip with the A-side and B-side titles above and below, with the artist in the middle. CD, or any number above 2, sets up an album-based skin.  If CD is used then 14 tracks will be displayed, if there is room (the number may be reduced automatically based on font size).

StripCount is the total number of visible strips (not selections) on the screen at once.

FontSmoothing turns on antialiasing for the font, which is highly recommended.

FontFocusColor is the color the song title changes to when the mouse passes over it.

FocusColor is the color of the dotted line surrounding the title when the mouse passes over it.

ShadowColor is the color that is filled in along the top and left when a song title is clicked on with a mouse.

Animation selects the way the strips move off the screen.  The only functioning values right now are SlideHorizontal and Disabled.


In the next post we'll define where the titlestrips appear.
« Last Edit: February 25, 2010, 10:26:35 AM by Chris »

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Skin creation tutorial
« Reply #4 on: October 30, 2008, 12:10:20 AM »
There are two ways to define the layout of the strips: You can define the position of each individual strip, or you can define a grid of strips.  You can actually combine these approaches, as you can define multiple Strips or StripGrids.  Why would you do this?  Both to have exact positioning control and to determine how the strips are numbered.

Titlestrips are numbered in the order they are encountered in the skin file.  For a grid, there is an Order setting to determine whether the strips are read horizontally or vertically.

So how does all this work in reality?  Let's say you are using Double strips and have letters A-E and numbers 1-4 for selections.  For some odd reason, let's say we've defined two individual strips, plus a 2x3 grid, followed by two more strips, laid out like this:

================ ==================
======STRIP1===== =======STRIP2======
================ ==================

================ =============== ================
===STRIPGRID3==== ===STRIPGRID3==== ===STRIPGRID3====
================ =============== ================

================ =============== ================
===STRIPGRID3==== ===STRIPGRID3==== ===STRIPGRID3====
================ =============== ================

================ ==================
======STRIP5===== =======STRIP4=====
================ ==================

Let's say StripGrid3 is set to Order=Vertical.  So how will these strips end up being numbered?

=A1============= =A3===============
======STRIP1===== =======STRIP2======
=A2============= =A4===============

=B1============= =C1============ =D1=============
===STRIPGRID3==== ===STRIPGRID3==== ===STRIPGRID3====
=B2============= =C2============ =D2=============

=B3============= =C3============ =D3=============
===STRIPGRID3==== ===STRIPGRID3==== ===STRIPGRID3====
=B4============= =C4============ =D4=============

=E3============= =E1===============
======STRIP5===== =======STRIP4=====
=E4============= =E2===============

I can't imagine why anyone would set things up this way, but the flexibility is there.

So let's look at the actual definition.  This skin uses a simple grid, so it's easy:

Code: [Select]
[StripGrid]
x=38
y=180
rows=4
cols=3
rowspace=8
colspace=43
order=Vertical

X and Y are the pixel locations of the upper left corner of the grid.  Rows and Cols define how many rows and columns there are in the grid, Rowspace and Colspace are the number of pixels between rows and columns, and Order is the order in which the strips are numbered.  If you leave out Rows, Cols, Rowspace, Colspace, and Order, you will define an individual strip.

Why is there no width and height for the individual strips?  We already set that up back in the Titlestrips section.

If you had more Strips or StripGrids, you just number them: [Strip1], [StripGrid2], etc.  The names Strip and StripGrid mean the same thing (thus you can't have both a Strip1 and a StripGrid1), it's just easier to use Strip if you mean only one strip as opposed to a grid.

Coming up next: defining on-screen buttons.
« Last Edit: February 25, 2010, 10:29:02 AM by Chris »

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Skin creation tutorial
« Reply #5 on: October 30, 2008, 12:28:42 AM »
On screen buttons and indicators are set up as Icons.  A clickable icon with a BTN_ action acts as a button, and a non-clickable icon with a MSG_ action acts as an indicator.

An Icon has an on state and an off state, triggered by a message from the jukebox.  (An Icon with its Action message set to MSG_START will be "on" all the time and can be used as an unchanging decal.)  Each state has an image to represent it; you can define these images or the jukebox can lift them off the screen area defined by the icon.

Code: [Select]
[Icon1]
x=157
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_1

This icon does not have an OnImage or an OffImage, so for the OffImage it's going to use what's on the screen, and for the OnImage it's going to shift that image down and to the right to appear "pressed".  X, Y, W, and H should be self-explanatory.  Clickable defines whether the icon is a pressable button and FocusColor defines the color of the dotted line that appears around the icon when the mouse is over it.

Action is the heart of the button; this sets the message that the icon sends or responds to.  The list of actions that an icon can generate or respond to are in the docs... they are probably the only thing that is fully documented.  These actions are generically referred to as "messages", and they represent the glue between the user interface and the jukebox engine. 

There are three types of messages: MSG_, which sends information to the user interface, BTN_, which represents a physical button press, and CMD_, which represents a command to the jukebox that is not from a button press.  You will probably never use a CMD_; they are generally used for internal use or timers and are not reflected back to the interface. 

The easy way to think of BTN_'s and MSG_'s is that a button tells the engine to do something, and a MSG_ tells the interface that something has happened.

Here's an example in detail: There is a clickable icon on the screen, Icon1, with an action of BTN_COIN1, and a non-clickable icon with an action of MSG_CREDIT, Icon2. The clickable icon is clicked and the button puts the message BTN_COIN1 into the message queue. On the screen, nothing happens yet.

The message processor picks up the message and reflects it to every icon on the screen.  Most icons are not listening for this message, so they ignore it.  Any icons with an Action of BTN_COIN1, however, will switch to their ON state.  The message processor, not knowing or caring what the icons did with that message, generates several more messages onto the message queue: a MSG_CREDITS message and three CMD_ADDCREDIT messages.  It also sets a timer for one-tenth of a second, after which it will send a -BTN_COIN1 to negate the original BTN_COIN1.  BTN_ messages are the only ones that have this timed un-set.

The message processor picks up the MSG_CREDITS message.  MSG_ messages take no actions, so the processor simply informs all of the icons about the message.  Icon2 is listening for this message so it switches to its ON image.

The message processor picks up the CMD_ADDCREDIT messages and adds 1 to the credit count for each one.  It also tells Display4 that its information is out of date and it needs to be refreshed (this is not handled by a message now, it eventually will).  CMD_ messages are not sent to the icons, so even an icon set to listen for it will never hear it.

A tenth of a second later, the -BTN_COIN1 message appears in the queue.  The message processor picks it up and sends it to all of the icons.  Icon1 is listening for this message and switches to its OFF image.  Icon2, however, will stay ON until the number of credits reaches zero, at which time the -MSG_CREDITS message will go into the queue and be sent to the icons.

The rest of the icons in the tutorial skin follow this same pattern.  Since they're all the same size and all in a row, only the X coordinate and the action changes:

Code: [Select]
[Icon2]
x=210
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_2

[Icon3]
x=264
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_3

[Icon4]
x=316
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_4

[Icon5]
x=369
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_5

[Icon6]
x=423
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_6

[Icon7]
x=476
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_7

[Icon8]
x=529
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_8

[Icon9]
x=601
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_SELECT

[Icon10]
x=654
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_POPULAR

[Icon11]
x=707
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_CLEAR

[Icon12]
x=761
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_RANDOM

[Icon13]
x=86
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_PREVPG

[Icon14]
x=32
y=689
w=47
h=53
Clickable=True
FocusColor=white
Action=BTN_NEXTPG

Last up: Sound effects.

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Skin creation tutorial
« Reply #6 on: October 30, 2008, 12:37:47 AM »
Sound effects can be added to the jukebox, set to trigger on specific messages.  THis is pretty straightforward: simply assign a WAV file to a message.

Code: [Select]
[Sounds]
BTN_COIN1=coin.wav
BTN_COIN2=coin.wav
BTN_COIN3=coin.wav
BTN_COIN4=coin.wav
MSG_INVALID=invalid.wav

There are two special things to note here: First, there is a special message called BTN_ANY that is only supported for sound effects; this allows you to put a generic "button click" sound on all buttons at once.  Second, you can set a sound effect for when a message turns off rather than on by putting a minus sign in front of the message name, like this:

-MSG_CREDITS=outofcredit.wav

You now should have a complete, working skin file!

Chris

  • Administrator
  • Hero Member
  • *****
  • Posts: 605
    • View Profile
    • DWJukebox
Re: Skin creation tutorial
« Reply #7 on: February 25, 2010, 11:14:29 AM »
Postscript: Adding an indicator

Having re-read my tutorial, I realize I have not talked about indicators at all.  As noted earlier (okay, maybe I talked about them a bit), an indicator is just a button that is not clickable.  Indicators, therefore, usually have MSG_ messages as their Action.  A good example to imagine is a Pause button with a Pause indicator next to it.  The Pause button would be marked as Clickable, would graphically look like a button, and have BTN_PAUSE as its action, where the Pause indicator would not be marked Clickable, would graphically look like a light or a text label, and have MSG_SONGPAUSE as its action.

An indicator without an action responds to MSG_START_SKIN by default, meaning it is always "on"; this can be used to add "decals" or other static features to a skin without modifying the background image.  We will use this method to add a label for an indicator.

Let's add a simple indicator to show if Radio mode is enabled.  We'll put this just above the control panel.  Fire up your favorite graphic editor and create a simple graphic that says "RADIO" on it.  The space we are working in is about 21 pixels high.  If you do not want to create a label at this time, you can download it from this post.  The sample image attached here is 49 pixels wide by 17 pixels high.

We now need to create the icon definition for the "decal".  We left off with Icon14, so we'll move on to Icon15.  (Note:  We could use Icon 16 if we wanted; the jukebox will keep looking after any "numbered" settings for the next 10 numbers before it gives up.  Thus, if you remove a setting from a numbered list, you don't need to re-number all the other settings.)

Code: [Select]
[Icon15]
x=6
y=648
w=49
h=17
Clickable=False
OnImage=radio.jpg
OffImage=radio.jpg

Since this is a "decal" we do not need an Action.  What we do need, however, is a way to point to our new image.  We do that with the OnIMage and OffImage settings.  We want this label to always be visible, so we will use the same image for both the OnImage and OffImage. Now for the indicator:

Code: [Select]
[Icon16]
x=60
y=651
w=11
h=11
Clickable=False
Action=MSG_RADIO
OnImage=r-ledon.bmp
OffImage=r-ledoff.bmp

r-ledon.bmp and r-ledoff.bmp are included with DWJukebox, as they are used in a few skins.

What if we wanted to make the RADIO label the indicator itself, with no light? We can do that too:

Code: [Select]
[Icon15]
x=6
y=648
w=49
h=17
Clickable=False
Action=MSG_RADIO
OnImage=radio.jpg

In this case we only need one icon, Icon15.  It now responds to the MSG_RADIO action and only has an OnImage.  If OffImage is missing, it just uses whatever was on the background at that location, so the label will just "disappear" when the message is off.

That concludes this tutorial.  What else would you like to see added on to this skin?  Let me know!