Send Me Your Themes

If you have made a dock theme, please do let me know at the following address and I'll add it here!

Read on for all the information on how you can create your own.

I Want It All And I Want It Now!

If you just want to quickly edit some graphics files to get a dock theme going without needing to know about all the details, you can now download a simple template theme here.

Template Theme

It's not pretty, but it should be enough to get you started - just replace the ugly flat coloured bitmaps with something nicer and you're done!

How To Make Themes

Making themes requires a certain degree of knowledge about editing XML files, and experience with a graphics application like Photoshop. It's not easy! Don't let that put you off of course, but I figured it was best telling you up front.

If you have any questions to do with themes, ask in the Theme section of the DragThing Forums

Ok, the first thing we need is a theme file to play with, so let's open up the DragThing application and take a look at the built-in ones.

Control or right-click on the DragThing application and choose "Show Package Contents" from the contextual menu that appears. Navigate down into the Contents / Resources / Themes folder inside the application and you'll find all the theme files.

Theme files are actually special folders with the extension ".dt5skin" (the extensions are all hidden in the folder above). Let's make a copy one of my first themes so we can modify it. Hold down option and drag the "Let's Be Bad Guys" file to your Desktop.

Control or right-click the copy, and again choose "Show Package Contents" from the menu.

You'll see that inside this theme, there are three files. The most important file is Theme.plist, but we'll come back to that in a minute.

The ".plist" files are actually XML files, and more specifically Property List Files. Apple uses this format for storing lots of different kinds of information on Mac OS X.

There are two ways of editing them. Since the files are really just plain text, I usually use Bare Bones' excellent text editor BBEdit.

The other way is to use Apple's Property List Editor application, which is optionally installed as part of the Developer Tools that came with your copy of Mac OS X. I'd actually recommend this second approach for beginners as it is very easy to damage the XML structure by mistake when you are editing the files as plain text.

So for all the examples below I will be using the Property List Editor. Let's look at all the files in turn.

Info.plist

First, let's open up the "Info.plist" file. Click on the disclosure triangle next to "Root" and you'll see the following list:

This small file contains some important bits of information about every theme, the most important being the CFBundleIdentifier entry.

CFBundleIdentifier
This is a string that DragThing uses to tell different theme files apart, so it needs to be unique. What I've done is just put the name of the theme (without spaces or capitals) at the end, I recommend you do the same.

CFBundleName
The name of the theme as displayed in DragThing. Try to pick something unique and memorable!

CFBundleShortVersionString / CFBundleVersion
The version of the theme. If you make a new version of a theme, you should increase the version number so people can tell them apart.

DTThemeAuthor
The name of the person who made this theme, which is displayed in the Appearance section of the DragThing Preferences window under the "Dock Theme" menu.

DTThemePreview
The name of a graphics file within the theme folder which is displayed in the "Dock Theme" menu as a preview of what the theme looks like.

DTThemeRequiredVersion
This is the minimum version of DragThing that the theme requires. You should set this to the version of DragThing you are using when you make the theme. It's likely that I'll add new features to the theme support in future versions of DragThing, and this lets older versions of DragThing know they won't be able to open it. Obviously it needs to be at least 5.7!

DTThemeURL
This is a URL that is displayed in the DragThing Preferences so the user can click on it and find out more information about your theme or you. If you don't have a website, just leave this pointing to the default page on dragthing.com.

Preview.png

Secondly Preview.png, this is the image referenced by the Info.plist file above. It can be in any standard format that QuickTime supports like PNG or JPEG, but make sure you change the name appropriately in the Info.plist. It's wise to make this file as small as possible otherwise your theme may become too large.

Theme.plist

Lastly, but most importantly, Theme.plist. This is the main file that describes how the theme looks. It's another plist - let's see what it looks like in Property List Editor.

Ok, that's a bit more complicated!

First, there's an enclosing dictionary called "Theme" which DragThing uses to tell this theme apart from other kinds of data. A dictionary is just a list of information, with each entry having a name, a type of data, and the data itself. Property List Editor sorts everything alphabetically.

Then there are more sub-dictionaries, one for each type of object described within the theme. All of these are optional, but if you leave them out the object will be drawn blank. Here's how it all maps visually to a dock.

Close
The close button displayed at the top left of the window.

Collapse
The collapse or minimise button displayed at the top left of the window.

Content
The content area of the dock window - that is, the area within the window not counting the titlebar and any borders round the outside of the window.

MiddleTab
A tab within the dock. It's "middle" because you can individually specify what the first, last and middle tabs look like - so you could have rounded corners on the first and last for example. Those are FirstTab, LastTab. There's also a SingleTab so you can make one tab on it's own look different too. The other are optional, DragThing will use the MiddleTab in place of them.

NameBar
The area where DragThing displays the name and other information about the dock item under the mouse.

Slot
The space for an individual dock item.

Slots
The combined area behind all the dock items and the name bar.

SupportsColours
Just a simple boolean flag that tells DragThing whether this theme lets the user pick their own colours. When this is set to "Yes", DragThing will show the Colour menu for docks.

Tabs
The area behind the tabs, running the full width or height of the dock.

TabSurround
The area immediately behind the tabs, running just the width of the tabs themselves.

TextColour
This sets the default colour used when drawing text in the dock. It can be overridden by individual objects by including a TextColour entry within their dictionaries.

Window
The overall look of the window, including the titlebar and borders. If you don't include a Window item, DragThing will use the default Mac OS window.

Zoom
The zoom button displayed at the top left of the window.

Dictionaries!

Now, within most of these dictionaries are even more dictionaries, and within them even more! It might look at little daunting at first, but I'll try to explain.

For example, if you click on the disclusure triangle, you can see that Window has three sub-dictionaries:

Horizontal
How the window looks with a horizontal titlebar along the top of the window.

NoTitlebar
How the window looks without a titlebar. This is also used for drawers.

Vertical
How the window looks with a vertical titlebar to the left of the window.

I'll come back to the other dictionaries in a minute. Let's go back and look at Close.

Again, it has Horizontal and Vertical entries to describe how the close button looks for windows with horizontal and vertical titlebars respectively.

Some elements, instead of having Horizontal and Vertical entries, have North, South, East, and West entries. The tabs are a good example, because they can point in any direction within the dock, regardless of the titlebar direction.

Let's dig deeper and look at the Horizontal case. Firstly it has a Border entry that specifies where on the window the close button appears. Many of the elements specify their sizing via a Border entry, although the don't all use it exactly the same way.

There's also a Background entry. This describes how the back of this element is drawn. Elements can also have a Foreground entry that is drawn over the top of any other content within itself. So, for example, if you look at the Blueprint theme, the grid pattern is drawn very faintly over the top of the icons.

Within the Background entry, there are more dictionaries repesenting different drawing states for the particular element, in this case Normal and Selected.

The interesting part is the Slices entry inside those, which finally contains the actual drawing.

Slices

This is where it gets really complicated :-)

Every element that is drawn in a dock is comprised of Slices. This is a list (or an Array in Property List terminology) of individual drawing commands.

Here's a simple slice.

This is an array with a single item in the list. Items in a Slices array are numbered starting with 0, and are processed in order from 0 onwards.

The Kind field specifies the type of drawing command. In this case, it's drawing an image, and the Name field specifies the name of the image file within the theme folder to use. These images can be of any standard format, though PNG is probably the best to use.

Now, themes don't have to use bitmap images like this - they can use simple drawing commands too. Here's a more complicated slice.

This draws a 50% translucent black oval, indented 2 pixels on each side.

And you can have as many slices as you like per element. Here's a list of the different Kinds of slices.

Image
Draws a bitmap image. Specify the name of the image within your theme in the Name parameter.

Fill
Fills the element with a colour or pattern or gradient. The Name parameter specifies the kind of fill. These are the allowed values.

Plain
Fill with a plain colour. Either specify the colour with a MainColour parameter, or DragThing will use the current layer colour the user has chosen (assuming SupportColours has been set to true in the Theme dictionary).

Metal
Fill using the Mac OS metal pattern.

Stripes
Fill using the Mac OS stripes pattern.

Gradient
Fill with a gradient. Specify the colours with MainColour, HighlightColour, and ShadowColour, or DragThing will use the current layer colours the user has chosen (assuming SupportColours has been set to true in the Theme dictionary).

You can also specify the following optional parameters.

Horizontal
A boolean value that determines if the gradient is drawn horizontally or vertically.

Diagonal
A boolean value that determines if the gradient is drawn diagonally.

Tube
A boolean value that determines if the gradient is drawn from ShadowColour to MainColour to HighlightColour to MainColour to ShadowColour again.

StartAlpha
A number (0.0 (transparent) to 1.0 (opaque)) that determines the alpha channel at the beginning of the gradient.

EndAlpha
A number (0.0 (transparent) to 1.0 (opaque)) that determines the alpha channel at the end of the gradient.

Mask
A special kind of slice that sets a clipping mask for the rest of the drawing for this element. You specify the kind of mask in the Name parameter. Each slice can also have a separate Mask parameter which is only active for that particular slice. These are the allowed values for both.

Rect
A simple rectangle

FrameRect
A border round a rectangle. Specify how thick in pixels using a Width parameter.

Oval
A simple oval

FrameOval
A border round an oval. Specify how thick in pixels using a Width parameter.

Diamond
A diamond shape.

RoundRect
A rectangle with rounded corners. Use a Radius parameter to specify how rounded.

RoundRectOptionalCorners
As RoundRect, but use the TopLeft, TopRight, BottomLeft, and BottomRight boolean parameters to say which corners are rounded.

FrameRoundRect
As RoundRect, but just a border. Specify how thick in pixels using a Width parameter.

FrameRoundRectOptionalCorners
As RoundRectOptionalCorners, but just a border. Specify how thick in pixels using a Width parameter.

InverseRect
As Rect, but inverted so that drawing only occurs outside the rectangle.

InverseRoundRect
As RoundRect, but inverted so that drawing only occurs outside the rounded rectangle.

InverseRoundRectOptionalCorners
Go on, guess!

Ying
The top half of a type of shape used in a lot of shiny Apple controls.

Yang
The bottom half of a type of shape used in a lot of shiny Apple controls.

Now, each slice also has a number of optional special parameters.

Alpha
How translucent to draw this slice. A number from 0.0 (transparent) to 1.0 (opaque).

DoNotRotate
A boolean value that specifies whether this slice should be drawn rotated. If you don't supply all the North / South / East / West versions of a particular element, DragThing will synthesise the missing ones by rotating the North one to fit. If you don't want this slice to rotate when that happens, set this to true.

Bounds
A dictionary that specifies the size and position of the drawing for this slice. You can add Height, Width, Top, Left, Bottom, and Right values. The values can either be numeric and interpreted as pixels, or strings that end in a % symbol which are treated as a percentage of the original size.

So Height of 50% with a Top of 0 would reduce the drawing size to half the height of the element, positioned at the top of the original rectangle.

And Top, Left, Bottom, Right of 10 would inset the drawing size by 10 pixels on all sides.

Images

There's one other thing to note. I said that if you were drawing images within slices, you could supply any standard format. DragThing add its own simple image format for themes, the "dt5image". You'll see a number of them in the built-in themes. These live within the theme folder, like any other image.

This isn't really a new image format, it's just a folder with the extension ".dt5image" that collects together multiple images into one object. It's useful for drawing complex images or repeating patterns.

You can supply images that are used to draw the corners and sides separately from the middle, and have the pieces stretch or tile as required. You could use this, for example, when drawing a window background. The corners would always stay the same size as the window resized.

There's another plist within every dt5image folder, the ThemeImage.plist file, so let's open it up.

As you can see, this is just a one-to-one mapping between the pieces in the picture above, and the actual graphics files within the folder. Here's another version that specifies that some of the pieces around the outside should be tiled rather than simply stretched to fill the space.

Also, you don't need to use all the pieces. Here's a basic tiled image which you could use for a background.

As with the main file, you can specify any kind of image, it doesn't need to be a PNG file.

The last trick of the dt5image is that is can specify alternate "Graphite" images which are used automatically when the user has set the Graphite theme in System Preferences.

The built-in themes use these mainly for the close / minimise / zoom buttons in the window, but you can use them anywhere.

Testing Themes

Double-clicking a theme file will automatically copy it to your user's Library/Application Support/DragThing/Themes folder, replacing any existing copies, and activate it, all in one go.

When I'm editing a theme, I'll usually add the theme itself to a dock, and sit in my editor of choice. When I've made a change to the theme, I'll save the file and just double-click the file to see the effect. You could also set up a hot key in DragThing (in the Item Options) to open the theme with a single keypress.

Summing Up

Well, that's the basics of dock theme development. The best thing to do is look at the existing themes and take them apart and see how they work. If you have any questions, feel free ask them in the Theme section on the forums and I'll do my best to help!

When you are done, please send me your themes, and I'll put the best of them up here for other people to download. I look forward to seeing what you can do!