Making a theme for Xfwm4

Just finished creating two variations of a Xfwm4 theme. That’s a lot of work! Not only do you have to come up with some idea as what kind of theme to create (the creative spark, the inspiration) but also have to slice, cut and modify the mockup you finally came up with.

And there are at minimum a whopping 42 XPM-images to a theme! And if you really want to take it that far, you can also create an overlay PNG-image for each of those. So a fully tricked out theme would have a total  84 (!) images you’d have to create.

That’s a lot of work and if you ever created one you know it’s also really repetitive and tedious. Hmm, repetitive and tedious, sounds like the perfect job for some scripts!

Since GIMP is seriously lacking in the slicing compartment I wrote a python-fu script that creates a new image for each visible path. It will set the mode of the new image to indexed, and then save it in the directory you specified, using the name of the path as file name.

That takes care of the slicing, but there is still the matter of editing the created XPMs to include the GTK theme color pickups. So I wrote a shell script to take care of that. You pass it two arguments, the first is the directory where you saved the slices to, and the second is the directory where it’ll put the modified XPMs.

But how does that script map a color in the image to a GTK theme color name? Well, I created a GIMP color palette that assigns each GTK theme color name to a color. If you now draw the mockup in those colors, that script can then modify it.

Since wordpress won’t let me upload tarballs or simple text files, you have to copy/paste the following… :-(


The python-fu plugin will/should add a new menu entry “Xfce Theme Tools/Export paths as index XPMs.”. Just create a few paths, name them, make ’em visible and use the script.

~/.gimp-<your gimp version>/plug-ins/slice-index-save.py

#!/usr/bin/env python
import os
from gimpfu import *

def slice_index_save( image, layer, output_dir ):
	path_join = os.path.join
	copy_visible = pdb.gimp_edit_copy_visible
	paste_as_new = pdb.gimp_edit_paste_as_new
	get_selection_bounds = pdb.gimp_selection_bounds
	convert_indexed = pdb.gimp_image_convert_indexed
	file_xpm_save = pdb.file_xpm_save

	image.undo_freeze()
	for vector in image.vectors:
		if not vector.visible:
			continue
		vector.to_selection()
		r = get_selection_bounds( image )[1:]
		width = r[2] - r[0]
		height = r[3] - r[1]
		copy_visible( image )
		new_image = paste_as_new()
		convert_indexed( new_image, NO_DITHER, MAKE_PALETTE, 255, False, True, "" )
		file_name = path_join( output_dir, "%s.xpm"%vector.name )
		file_xpm_save(
			new_image, new_image.layers[0],
			file_name, file_name, 127 )
		gimp.delete( new_image )
		gimp.displays_flush()
	image.undo_thaw()

register(
	#func name
	"python-fu-slice-index-save",
	#menu label
	"Xfwm Theme ...",
	#description
	"Export paths as indexed XPMs.",
	#author
	"alt.e-mail@gmx.de",
	#copyright notice
	"copyright 2009, alt.e-mail@gmx.de",
	#date created
	"Februar 03, 2009",
	#menu path
	"Export paths as indexed XPMs.",
	#image type that the script works on
	"RGB*",
	[	( PF_IMAGE, "image", "Input Image", 0 ),
		( PF_DRAWABLE, "layer", "Input Layer", 0 ),
		( PF_DIRNAME, "output_dir", "Output Directory:", "" )
	],
	[],
	slice_index_save,
	menu="<Image>/Xfce Theme Tools"
)

main()

~/.gimp-<your gimp version>/palettes/Xfwm.gpl

GIMP Palette
Name: Xfwm
Columns: 10
#
102 102 102	inactive_color_1
254 254 254	inactive_hilight_1
 64  64  64	inactive_shadow_1
 80  80  80	inactive_mid_1
208 208 208	inactive_color_2
240 240 240	inactive_hilight_2
 96  96  96	inactive_shadow_2
192 192 192	inactive_mid_2
  0   0   0	inactive_text_color
 16  16  16	inactive_border_color
 80 128 208	active_color_1
128 160 238	active_hilight_1
 59  87 136	active_shadow_1
104 124 158	active_mid_1
221 221 221	active_color_2
255 255 255	active_hilight_2
102 102 102	active_shadow_2
190 190 190	active_mid_2
254 254 255	active_text_color
 17  34  51	active_border_color

~/xfwm4-build-theme.sh

#!/bin/bash

# arguments
SCRIPT=$(basename $(readlink -f $0))
IN_DIR=$1
OUT_DIR=$2
if [ ! "$IN_DIR" -o ! "$OUT_DIR" ]; then
	echo "usage: $SCRIPT  " >&2
	exit 1
fi

# check if input directory exists
IN_DIR=$(readlink -f "$1")
if [ ! -d "$IN_DIR" ]; then
	echo "input directory ('$IN_DIR') does not exist." >&2
	exit 1
fi

# clean paths
OUT_DIR=$(readlink -f "$2")

# don't want to be using same output directory as input directory
if [ "$IN_DIR" = "$OUT_DIR" ]; then
	echo "output directory should not be the same as input directory." >&2
	echo "    input directory was: $IN_DIR" >&2
	echo "    ouput directory was: $OUT_DIR" >&2
	exit 1
fi

# clean/create output directory
if [ -d "$OUT_DIR" ]; then
	for pixmap in $(echo {top-{left,right},title-{1,2,3,4,5},\
left,right,bottom{-left,-right,}}-{active,inactive}.xpm \
{menu,stick,shade,hide,maximize,close}-{active,inactive,pressed}.xpm); do
		rm -f "$OUT_DIR/$pixmap"
	done
else
	mkdir "$OUT_DIR"
fi

cp "$IN_DIR"/*.xpm "$OUT_DIR"
# setting colors
sed -i \
-e 's/c #5080D0"/c #5080D0 s active_color_1"/g' \
-e 's/c #80A0EE"/c #80A0EE s active_hilight_1"/g' \
-e 's/c #3B5788"/c #3B5788 s active_shadow_1"/g' \
-e 's/c #687C9E"/c #687C9E s active_mid_1"/g' \
-e 's/c #DDDDDD"/c #DDDDDD s active_color_2"/g' \
-e 's/c #FFFFFF"/c #FFFFFF s active_hilight_2"/g' \
-e 's/c #666666"/c #666666 s active_shadow_2"/g' \
-e 's/c #BEBEBE"/c #BEBEBE s active_mid_2"/g' \
-e 's/c #FEFEFF"/c #FEFEFF s active_text_color"/g' \
-e 's/c #112233"/c #112233 s active_border_color"/g' \
-e 's/c #666666"/c #666666 s inactive_color_1"/g' \
-e 's/c #FEFEFE"/c #FEFEFE s inactive_hilight_1"/g' \
-e 's/c #404040"/c #404040 s inactive_shadow_1"/g' \
-e 's/c #505050"/c #505050 s inactive_mid_1"/g' \
-e 's/c #D0D0D0"/c #D0D0D0 s inactive_color_2"/g' \
-e 's/c #F0F0F0"/c #F0F0F0 s inactive_hilight_2"/g' \
-e 's/c #606060"/c #606060 s inactive_shadow_2"/g' \
-e 's/c #C0C0C0"/c #C0C0C0 s inactive_mid_2"/g' \
-e 's/c #000000"/c #000000 s inactive_text_color"/g' \
-e 's/c #101010"/c #101010 s inactive_border_color"/g' \
"$OUT_DIR"/*.xpm

sed -i -e 's/_active/_inactive/g' "$OUT_DIR"/*-inactive.xpm
sed -i -e 's/_active/_pressed/g' "$OUT_DIR"/*-pressed.xpm

So, that is exactly why I’m sticking to Linux. I can just quickly automate stuff I want done, without having to buy into obscure and messy solutions. Then again, shell and python scripting is considered mastery of the black arts by some ;-P.

Oh, and you can find the Xfwm4-themes I created here:

Leave a comment if you made something cool with it or you have suggestions, I’ll appreciate it!

Advertisements

2 Responses to Making a theme for Xfwm4

  1. gadi says:

    Wow man, not only you have done those fantastic XFWM themes, you have wrote scripts to help doing one! SImply great.

    Seriously, love your work. I’ll probe those scripts. Thanks for all, one more time ;)

  2. thezbyg says:

    The python script has bug
    menu=”<Imagegt;/Xfce Theme Tools”
    should be
    menu=”<Image>/Xfce Theme Tools”

    edit: Fixed, thanks ;-)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: