foo_title component

foo_title is my component for foobar2000. Foobar2000 is a music player suitable for advanced users. foo_title's purpose is to show the currently playing song on the top of the screen all the time (something like winamp's windowshade mode). It supports custom-made skins and it's written in C# (with some C++/CLI for binding to foobar, of course). Therefore, you need the .NET Framework 2.0.

Download

You can get the component here. It includes three my skins. The current version is 0.7 as of April the 29th 2007.

Hosted at SourceForge.net Logo

Screenshots

An image of foo_title

What's new ?

First of all, this component is ported to foobar2000 v. 0.9 and it won't work with older releases. I've rewritten a lot of code.

0.7 Changelog

0.6 Changelog

These changes are backward compatible, so all your current skins will work in 0.7 as well.

All changes in skins from previous version is marked like this paragraph.

Installation

Installation is quite easy now. You just need to put the files from the archive to foobar's directory, so that the dlls go to the components directory and there is a new directory called foo_title. This directory contains the skins.

Creating skins

foo_title skins consist of one XML and some image files. The XML file describes where and which images to draw. Supported image formats are those supported by the .NET framework - that is bmp, jpg, .png (for transparent images) and perhaps more.

Each skin has it's own directory under foo_title. The skin.xml must exist in that directory and it has the following structure:

foo_title XML skin structure

The main element is skin. It has the following attributes:

author
Who's the author of this skin. This information is not shown anywhere yet, but it's nice to know
name
The name of this skin. This is quite useless :)
width
This is the initial width of the window. However the width is adjusted automatically.
height
This is the initiali height of the window, but it is also automatically adjusted.

So the beginning of the xml file should be something like

<?xml version="1.0" encoding="utf-8"?>

<skin
    author="Roman Plasil"
    name="White skin"
    width="400"
    height="22">

The main element contains one or more layer elements. Each layer can contain more layers, so it's not a layer in the original sense, because they can be nested.

Each layer has a geometry element which defines the layer's position, size and it's behaviour when it's resized.

The layer element looks like this :

    <layer name="main" type="absolute-images">
        <geometry type="absolute">
            <size x="370" y="58" />
            <position x="0" y="0" align="left" />
        </geometry>

        <contents>
            <image src="main.png" />
        </contents>
        <!-- optionally, another <layer> element (or more) go here -->
   </layer>

 

The name attribute is just informative, however type is more important. It chooses the way the content is displayed. More on this later.

Layer's geometry

Each layer has got it's geometry, which defines it's position and size within the parent layer. There are two types of geometries:

Almost all the entries in the layer's geometry (size, position, padding) can now contain foobar2000 formatting strings. Everything that works in foobar2000 will work here as well, see titleformat_help.html in your foobar directory for further reference. Please note that this feature when used is slightly more resource demanding (one needs to recalculate the sizes and positions each update, that is usually every 100 ms). Also, unless the string contains a $ or %, it is not evaluated as a formatting string (for performance reasons). But that shouldn't cause any problems, because as far as I know, all formatting strings contain these characters.

A trackbar can be created using an absolute geometry with position similar to the following:

<position x="$add(41, $mul(4, $div($mul(%playback_time_seconds%, 94), %length_seconds%)))" y="19" align="left" />
            

full
The layer occupies as much space as possible - the whole client area of the parent layer. full type requires a padding element with the following attributes: left, top, right, bottom. These attributes adjust the position of the client area of the layer within the parent layer. For example:
<geometry type="full">
    <padding left="66" top="4" right="55" bottom="0" />
</geometry>
absolute
The layer has fixed absolute size. It has a position subelement with the x, y and align attributes. Align can be either left or right. The x and y attributes adjust the position of the layer relative to it's alignment. For example:
<geometry type="absolute">
    <size x="200" y="22" />
    <position x="0" y="0" align="left" />
</geometry>

Example of layers 1 Example of layers 2 - enlarged For example, the red layer has a full-type geometry with padding set to all 0's, except for right which is set to something about 60. It contains another layer with a full-geometry (the green one) and you can see that it has large top and right padding and a small left and bottom padding. When the containing (white) layer is resized, the full-geometry layers automatically adjust their sizes. The blue layer has an absolute-geometry and it is not resized. It's align is set to right and you can see that it moves when the red layer is resized.

Layer types

Now that you (hopefully) understand how the layers are placed and sized, let's have a look at what can they contain.

There are the following types of layers:

fill-images
Contains 3 images which are drawn besides to allow nice resizing. One image for the left side, one center image and one image for the right side:
<contents>
    <image position="left" src="white\left_back.png" />
    <image position="center" repeat="true" src="white\repeat_back.png" />
    <image position="right" src="white\right_back.png" />
</contents>
The center image has the repeat attribute, which can be either true or false depending whether you want the center image to repeat or be stretched.
text
This layer just displays some text and it looks like this:
        <contents spacing="20" font="Verdana" size="8" bold="true" italic="true">
            <defaultText>foobar2000</defaultText>
            <label position="left" color="ff1234f6" bold="false" font="tahoma" >%artist% '('%album%')' - %title%</label>
            <label position="right" color="ff000000">%_time_elapsed%/%_length%</label>
        </contents>
spacing is the space between the left and right labels. The color defines the color in a similar way to HTML colors. The first 2 numbers is alpha. As you can see, the text layer uses foobar's title formatting. This is the only layer which can resize the skin. It does so according to text width. Layer's geometry must be full for resizing to work.

Now you can specify font, size, color, italic and bold attributes in both labels and in the contents node. The values written in the contents node are taken as default and can be overriden in the labels. So in the example above, the left label would be italic, Tahoma of size 8.

The contents layer can also have a defaultText element, which is shown when nothing is playing and on startup.

scrolling-text
Scrolling text is almost the same as normal text, except the following:
absolute-images
Displays images stretched to full size of the layer, one over another.
<contents>
    <image src="default\logo.png"/> 
</contents>
animation
Plays repeatedly an animation stretched to full size of the layer.
<contents>
    <frame src="white\logoa1.png" />
    <frame src="white\logoa2.png" />
    <frame src="white\logoa3.png" />
    <frame src="white\logoa4.png" />
    <frame src="white\logoa5.png" />
    <frame src="white\logoa6.png" />
    <frame src="white\logoa5.png" />
    <frame src="white\logoa4.png" />
    <frame src="white\logoa3.png" />
    <frame src="white\logoa2.png" />
</contents>
album-art
This layer displays the album art. Each user can configure the filenames in preferences. There is one subelement, NoAlbumArt which defines the image to show when no album art was shown.
<contents>
    <NoAlbumArt>
        noAlbumArt.png
    </NoAlbumArt>
</contents>
                
button
This layer creates a clickable button. It's subelement action defines the action to do. It can be any command from the main menu, like Play. The subelements normalImg, overImg, downImg select which images to use for the button in the three states.
<contents>
    <action>
        Next
    </action>
    <normalImg src="buttons-normal_07.png" />
    <overImg src="buttons-over_07.png" />
    <downImg src="buttons-down_07.png" />
</contents>
                

See the XML's of the attached skins and feel free to use them as a starting point for your own skins.