/** @brief Pop-up menu for new tracks list */
static struct menuitem added_menuitems[] = {
- { "Track properties", ql_properties_activate, ql_properties_sensitive, 0, 0 },
- { "Play track", ql_play_activate, ql_play_sensitive, 0, 0 },
- { "Select all tracks", ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
- { "Deselect all tracks", ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
+ { "Track properties", GTK_STOCK_PROPERTIES, ql_properties_activate, ql_properties_sensitive, 0, 0 },
+ { "Play track", GTK_STOCK_MEDIA_PLAY, ql_play_activate, ql_play_sensitive, 0, 0 },
+ { "Select all tracks", GTK_STOCK_SELECT_ALL, ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
+ { "Deselect all tracks", NULL, ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
};
struct queuelike ql_added = {
static struct menuitem choose_menuitems[] = {
{
"Play track",
+ GTK_STOCK_MEDIA_PLAY,
choose_play_activate,
choose_play_sensitive,
0,
},
{
"Track properties",
+ GTK_STOCK_PROPERTIES,
choose_properties_activate,
choose_properties_sensitive,
0,
},
{
"Select children",
+ NULL,
choose_selectchildren_activate,
choose_selectchildren_sensitive,
0,
},
{
"Play children",
+ NULL,
choose_playchildren_activate,
choose_selectchildren_sensitive, /* re-use */
0,
},
{
"Deselect all tracks",
+ NULL,
choose_selectnone_activate,
choose_selectnone_sensitive,
0,
/*
* This file is part of DisOrder.
- * Copyright (C) 2006-2008 Richard Kettlewell
+ * Copyright (C) 2006-2009 Richard Kettlewell
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
struct icon;
-static void clicked_icon(GtkButton *, gpointer);
+static void clicked_icon(GtkToolButton *, gpointer);
+static void toggled_icon(GtkToggleToolButton *button,
+ gpointer user_data);
static void clicked_menu(GtkMenuItem *, gpointer userdata);
static void toggled_menu(GtkCheckMenuItem *, gpointer userdata);
/** @brief Guard against feedback */
int suppress_actions = 1;
+/** @brief Toolbar widget */
+static GtkWidget *toolbar;
+
/** @brief Definition of an icon
*
* We have two kinds of icon:
* (All icons can be sensitive or insensitive, separately to the above.)
*/
struct icon {
- /** @brief Filename for 'on' image */
- const char *icon_on;
+ /** @brief TRUE to use GTK+ stock icons instead of filenames */
+ gboolean stock;
+
+ /** @brief TRUE for toggle buttons, FALSE for action buttons */
+ gboolean toggle;
+
+ /** @brief Filename for image or stock string */
+ const char *icon;
/** @brief Text for 'on' tooltip */
const char *tip_on;
- /** @brief Filename for 'off' image or NULL for an action icon */
- const char *icon_off;
-
- /** @brief Text for 'off tooltip */
+ /** @brief Text for 'off' tooltip */
const char *tip_off;
/** @brief Associated menu item or NULL */
const char *menuitem;
+ /** @brief Label text */
+ const char *label;
+
/** @brief Events that change this icon, separated by spaces */
const char *events;
/** @brief Pointer to menu item */
GtkWidget *item;
- GtkWidget *image_on;
- GtkWidget *image_off;
+ GtkWidget *image;
};
static int pause_resume_on(void) {
- return !(last_state & DISORDER_TRACK_PAUSED);
+ return !!(last_state & DISORDER_TRACK_PAUSED);
}
static int pause_resume_sensitive(void) {
- return !!(last_state & DISORDER_PLAYING)
+ return playing_track
+ && !!(last_state & DISORDER_PLAYING)
&& (last_rights & RIGHT_PAUSE);
}
/** @brief Table of all icons */
static struct icon icons[] = {
{
- icon_on: "pause32.png",
- tip_on: "Pause playing track",
- icon_off: "play32.png",
- tip_off: "Resume playing track",
+ toggle: TRUE,
+ stock: TRUE,
+ icon: GTK_STOCK_MEDIA_PAUSE,
+ label: "Pause",
+ tip_on: "Resume playing track",
+ tip_off: "Pause playing track",
menuitem: "<GdisorderMain>/Control/Playing",
on: pause_resume_on,
sensitive: pause_resume_sensitive,
- action_go_on: disorder_eclient_resume,
- action_go_off: disorder_eclient_pause,
- events: "pause-changed playing-changed rights-changed",
+ action_go_on: disorder_eclient_pause,
+ action_go_off: disorder_eclient_resume,
+ events: "pause-changed playing-changed rights-changed playing-track-changed",
},
{
- icon_on: "cross32.png",
+ stock: TRUE,
+ icon: GTK_STOCK_STOP,
+ label: "Scratch",
tip_on: "Cancel playing track",
menuitem: "<GdisorderMain>/Control/Scratch",
sensitive: scratch_sensitive,
events: "playing-track-changed rights-changed",
},
{
- icon_on: "randomenabled32.png",
+ toggle: TRUE,
+ stock: FALSE,
+ icon: "cards24.png",
+ label: "Random",
tip_on: "Disable random play",
- icon_off: "randomdisabled32.png",
tip_off: "Enable random play",
menuitem: "<GdisorderMain>/Control/Random play",
on: random_enabled,
events: "random-changed rights-changed",
},
{
- icon_on: "playenabled32.png",
+ toggle: TRUE,
+ stock: TRUE,
+ icon: GTK_STOCK_MEDIA_PLAY,
+ label: "Play",
tip_on: "Disable play",
- icon_off: "playdisabled32.png",
tip_off: "Enable play",
on: playing_enabled,
sensitive: playing_sensitive,
events: "enabled-changed rights-changed",
},
{
- icon_on: "rtpenabled32.png",
+ toggle: TRUE,
+ stock: TRUE,
+ icon: GTK_STOCK_CONNECT,
+ label: "RTP",
tip_on: "Stop playing network stream",
- icon_off: "rtpdisabled32.png",
tip_off: "Play network stream",
menuitem: "<GdisorderMain>/Control/Network player",
on: rtp_enabled,
/** @brief Create the control bar */
GtkWidget *control_widget(void) {
- GtkWidget *hbox = gtk_hbox_new(FALSE, 1), *vbox;
+ GtkWidget *hbox = gtk_hbox_new(FALSE, 1);
int n;
D(("control_widget"));
assert(mainmenufactory); /* ordering must be right */
+ toolbar = gtk_toolbar_new();
+ /* Don't permit overflow arrow as otherwise the toolbar isn't greedy enough
+ * in asking for space. The ideal is probably to make the volume and balance
+ * sliders hang down from the toolbar so it unavoidably gets the whole width
+ * of the window to play with. */
+ gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), FALSE);
+ gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),
+ full_mode ? GTK_TOOLBAR_BOTH : GTK_TOOLBAR_ICONS);
for(n = 0; n < NICONS; ++n) {
- /* Create the button */
- icons[n].button = gtk_button_new();
+ struct icon *const icon = &icons[n];
+ icon->button = (icon->toggle
+ ? GTK_WIDGET(gtk_toggle_tool_button_new())
+ : GTK_WIDGET(gtk_tool_button_new(NULL, NULL)));
gtk_widget_set_style(icons[n].button, tool_style);
- icons[n].image_on = gtk_image_new_from_pixbuf(find_image(icons[n].icon_on));
- gtk_widget_set_style(icons[n].image_on, tool_style);
- g_object_ref(icons[n].image_on);
- /* If it's a toggle icon, create the 'off' half too */
- if(icons[n].icon_off) {
- icons[n].image_off = gtk_image_new_from_pixbuf(find_image(icons[n].icon_off));
- gtk_widget_set_style(icons[n].image_off, tool_style);
- g_object_ref(icons[n].image_off);
+ if(icons[n].stock) {
+ /* We'll use the stock icons for this one */
+ icon->image = gtk_image_new_from_stock(icons[n].icon,
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ } else {
+ /* Create the 'on' image */
+ icon->image = gtk_image_new_from_pixbuf(find_image(icons[n].icon));
}
- g_signal_connect(G_OBJECT(icons[n].button), "clicked",
- G_CALLBACK(clicked_icon), &icons[n]);
- /* pop the icon in a vbox so it doesn't get vertically stretch if there are
- * taller things in the control bar */
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), icons[n].button, TRUE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+ assert(icon->image);
+ gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(icon->button),
+ icon->image);
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(icon->button),
+ icon->label);
+ if(icon->toggle)
+ g_signal_connect(G_OBJECT(icon->button), "toggled",
+ G_CALLBACK(toggled_icon), icon);
+ else
+ g_signal_connect(G_OBJECT(icon->button), "clicked",
+ G_CALLBACK(clicked_icon), icon);
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
+ GTK_TOOL_ITEM(icon->button),
+ -1);
if(icons[n].menuitem) {
/* Find the menu item */
icons[n].item = gtk_item_factory_get_widget(mainmenufactory,
icons[n].menuitem);
- if(icons[n].icon_off)
+ if(icon->toggle)
g_signal_connect(G_OBJECT(icons[n].item), "toggled",
G_CALLBACK(toggled_menu), &icons[n]);
else
gtk_widget_set_style(balance_widget, tool_style);
gtk_scale_set_digits(GTK_SCALE(volume_widget), 10);
gtk_scale_set_digits(GTK_SCALE(balance_widget), 10);
- gtk_widget_set_size_request(volume_widget, 192, -1);
- gtk_widget_set_size_request(balance_widget, 192, -1);
+ gtk_widget_set_size_request(volume_widget, 128, -1);
+ gtk_widget_set_size_request(balance_widget, 128, -1);
gtk_widget_set_tooltip_text(volume_widget, "Volume");
gtk_widget_set_tooltip_text(balance_widget, "Balance");
- gtk_box_pack_start(GTK_BOX(hbox), volume_widget, FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), balance_widget, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), toolbar,
+ FALSE/*expand*/, TRUE/*fill*/, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), volume_widget,
+ FALSE/*expand*/, TRUE/*fill*/, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), balance_widget,
+ FALSE/*expand*/, TRUE/*fill*/, 0);
/* space updates rather than hammering the server */
gtk_range_set_update_policy(GTK_RANGE(volume_widget), GTK_UPDATE_DELAYED);
gtk_range_set_update_policy(GTK_RANGE(balance_widget), GTK_UPDATE_DELAYED);
int on = icon->on ? icon->on() : 1;
int sensitive = icon->sensitive ? icon->sensitive() : 1;
//fprintf(stderr, "sensitive->%d\n", sensitive);
- GtkWidget *child, *newchild;
++suppress_actions;
/* If the connection is down nothing is ever usable */
if(!(last_state & DISORDER_CONNECTED))
sensitive = 0;
- //fprintf(stderr, "(checked connected) sensitive->%d\n", sensitive);
- /* Replace the child */
- newchild = on ? icon->image_on : icon->image_off;
- child = gtk_bin_get_child(GTK_BIN(icon->button));
- if(child != newchild) {
- if(child)
- gtk_container_remove(GTK_CONTAINER(icon->button), child);
- gtk_container_add(GTK_CONTAINER(icon->button), newchild);
- gtk_widget_show(newchild);
- }
+ if(icon->toggle)
+ gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(icon->button),
+ on);
/* If you disable play or random play NOT via the icon (for instance, via the
* edit menu or via a completely separate command line invocation) then the
* icon shows up as insensitive. Hover the mouse over it and the correct
gtk_widget_set_sensitive(icon->button, sensitive);
/* Icons with an associated menu item */
if(icon->item) {
- if(icon->icon_off)
+ if(icon->toggle)
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(icon->item), on);
gtk_widget_set_sensitive(icon->item, sensitive);
}
popup_protocol_error(0, err);
}
-static void clicked_icon(GtkButton attribute((unused)) *button,
+static void clicked_icon(GtkToolButton attribute((unused)) *button,
gpointer userdata) {
const struct icon *icon = userdata;
if(suppress_actions)
return;
- if(!icon->on || icon->on())
+ icon->action_go_off(client, icon_action_completed, 0);
+}
+
+static void toggled_icon(GtkToggleToolButton attribute((unused)) *button,
+ gpointer user_data) {
+ const struct icon *icon = user_data;
+
+ if(suppress_actions)
+ return;
+ if(icon->on())
icon->action_go_off(client, icon_action_completed, 0);
else
icon->action_go_on(client, icon_action_completed, 0);
static void toggled_menu(GtkCheckMenuItem attribute((unused)) *menuitem,
gpointer userdata) {
- clicked_icon(NULL, userdata);
+ toggled_icon(NULL, userdata);
}
/** @brief Called when a volume command completes */
gtk_widget_hide(balance_widget);
gtk_scale_set_value_pos(GTK_SCALE(volume_widget), GTK_POS_RIGHT);
}
+ gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),
+ full_mode ? GTK_TOOLBAR_BOTH : GTK_TOOLBAR_ICONS);
}
/*
/** @brief Create and populate the main window */
static void make_toplevel_window(void) {
- GtkWidget *const vbox = gtk_vbox_new(FALSE, 1);
+ GtkWidget *const vbox = gtk_vbox_new(FALSE/*homogeneous*/, 1/*spacing*/);
GtkWidget *const rb = report_box();
D(("top_window"));
padding: 8px
}
+td:first-child {
+ text-align: right
+}
+
table {
margin-left: 2em
}
<tr>
<td><img src="button-pause.png"></td>
<td>The pause button. This only effective when a track is
- playing. When it is pressed the playing track is paused and
- the button turns into a “play” icon instead.</td>
+ playing. When it is pressed the playing track is paused.</td>
</tr>
<tr>
<tr>
<td><img src="button-random.png"></td>
- <td>The random play button. Random play means that if
+
+ <td>The random play button. Random play, which is enabled
+ when the button is depressed, means that if
nothing is playing the server will automatically pick a track
at random and play that. Furthermore it will ensure that the
queue always has a minimum number of tracks, so you can see
- ahead of time what will play next.<br>
- As shown, random play is disabled. The button goes green
- when it is enabled.</td>
+ ahead of time what will play next.</td>
</tr>
<tr>
<td><img src="button-playing.png"></td>
<td>The playing button. Normally this would always be left
- enabled (green). If it is disabled then nothing will be
+ enabled, i.e. with the button depressed.
+ If it is disabled then nothing will be
played at all, regardless of whether it was randomly chosen
or picked by a human.</td>
</tr>
server is playing over the network (as opposed to using a
local sound card). When network play is enabled,
Disobedience runs a client program on your computer to play
- sound received over the network using your sound card.<br>
- As shown, network play is disabled. The button goes green
- when it is enabled.</td>
+ sound received over the network using your sound card.</td>
</tr>
</table>
(char *)"<CTRL>A", /* accelerator */
menu_tab_action, /* callback */
offsetof(struct tabtype, selectall_activate), /* callback_action */
- 0, /* item_type */
- 0 /* extra_data */
+ (char *)"<StockItem>", /* item_type */
+ GTK_STOCK_SELECT_ALL, /* extra_data */
},
{
(char *)"/Edit/Deselect all tracks", /* path */
0, /* accelerator */
menu_tab_action, /* callback */
offsetof(struct tabtype, properties_activate), /* callback_action */
- 0, /* item_type */
- 0 /* extra_data */
+ (char *)"<StockItem>", /* item_type */
+ GTK_STOCK_PROPERTIES, /* extra_data */
},
{
(char *)"/Edit/Edit playlists", /* path */
(char *)"<CTRL>S", /* accelerator */
0, /* callback */
0, /* callback_action */
- 0, /* item_type */
- 0 /* extra_data */
+ (char *)"<StockItem>", /* item_type */
+ GTK_STOCK_STOP, /* extra_data */
},
{
(char *)"/Control/Playing", /* path */
0, /* accelerator */
manual_popup, /* callback */
0, /* callback_action */
- 0, /* item_type */
- 0 /* extra_data */
+ (char *)"<StockItem>", /* item_type */
+ GTK_STOCK_HELP, /* extra_data */
},
{
(char *)"/Help/About DisOrder", /* path */
* - select/deselect all work
*/
static struct menuitem playlist_menuitems[] = {
- { "Track properties", ql_properties_activate, ql_properties_sensitive, 0, 0 },
- { "Play track", ql_play_activate, ql_play_sensitive, 0, 0 },
- { "Play playlist", playlist_playall_activate, playlist_playall_sensitive, 0, 0 },
- { "Remove track from playlist", playlist_remove_activate, playlist_remove_sensitive, 0, 0 },
- { "Select all tracks", ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
- { "Deselect all tracks", ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
+ { "Track properties", GTK_STOCK_PROPERTIES, ql_properties_activate, ql_properties_sensitive, 0, 0 },
+ { "Play track", GTK_STOCK_MEDIA_PLAY, ql_play_activate, ql_play_sensitive, 0, 0 },
+ { "Play playlist", NULL, playlist_playall_activate, playlist_playall_sensitive, 0, 0 },
+ { "Remove track from playlist", GTK_STOCK_DELETE, playlist_remove_activate, playlist_remove_sensitive, 0, 0 },
+ { "Select all tracks", GTK_STOCK_SELECT_ALL, ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
+ { "Deselect all tracks", NULL, ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
};
static const GtkTargetEntry playlist_targets[] = {
static struct menuitem playlist_picker_menuitems[] = {
{
"Select playlist",
+ NULL,
playlist_picker_select_activate,
playlist_picker_select_sensitive,
0,
},
{
"Play playlist",
+ GTK_STOCK_MEDIA_PLAY,
playlist_picker_play_activate,
playlist_picker_play_sensitive,
0,
},
{
"Remove playlist",
+ GTK_STOCK_DELETE,
playlist_picker_remove_activate,
playlist_picker_remove_sensitive,
0,
g_signal_connect(menu, "destroy",
G_CALLBACK(gtk_widget_destroyed), menup);
for(int n = 0; n < nitems; ++n) {
- items[n].w = gtk_menu_item_new_with_label(items[n].name);
+ if(items[n].stock) {
+ GtkWidget *image = gtk_image_new_from_stock(items[n].stock,
+ GTK_ICON_SIZE_MENU);
+ items[n].w = gtk_image_menu_item_new_with_label(items[n].name);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(items[n].w),
+ image);
+ } else
+ items[n].w = gtk_menu_item_new_with_label(items[n].name);
/* TODO accelerators would be useful here. There might be some
* interaction with the main menu accelerators, _except_ for playlist
* case! */
/** @brief Menu item name */
const char *name;
+ /** @brief Stock icon name */
+ const char *stock;
+
/** @brief Called to activate the menu item */
void (*activate)(GtkMenuItem *menuitem,
gpointer user_data);
/** @brief Pop-up menu for queue */
static struct menuitem queue_menuitems[] = {
- { "Track properties", ql_properties_activate, ql_properties_sensitive, 0, 0 },
- { "Select all tracks", ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
- { "Deselect all tracks", ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
- { "Scratch playing track", ql_scratch_activate, ql_scratch_sensitive, 0, 0 },
- { "Remove track from queue", ql_remove_activate, ql_remove_sensitive, 0, 0 },
- { "Adopt track", ql_adopt_activate, ql_adopt_sensitive, 0, 0 },
+ { "Track properties", GTK_STOCK_PROPERTIES, ql_properties_activate, ql_properties_sensitive, 0, 0 },
+ { "Select all tracks", GTK_STOCK_SELECT_ALL, ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
+ { "Deselect all tracks", NULL, ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
+ { "Scratch playing track", GTK_STOCK_STOP, ql_scratch_activate, ql_scratch_sensitive, 0, 0 },
+ { "Remove track from queue", GTK_STOCK_DELETE, ql_remove_activate, ql_remove_sensitive, 0, 0 },
+ { "Adopt track", NULL, ql_adopt_activate, ql_adopt_sensitive, 0, 0 },
};
static const GtkTargetEntry queue_targets[] = {
/** @brief Pop-up menu for recently played list */
static struct menuitem recent_menuitems[] = {
- { "Track properties", ql_properties_activate, ql_properties_sensitive,0, 0 },
- { "Play track", ql_play_activate, ql_play_sensitive, 0, 0 },
- { "Select all tracks", ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
- { "Deselect all tracks", ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
+ { "Track properties", GTK_STOCK_PROPERTIES, ql_properties_activate, ql_properties_sensitive,0, 0 },
+ { "Play track", GTK_STOCK_MEDIA_PLAY, ql_play_activate, ql_play_sensitive, 0, 0 },
+ { "Select all tracks", GTK_STOCK_SELECT_ALL, ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
+ { "Deselect all tracks", NULL, ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
};
struct queuelike ql_recent = {
#
# This file is part of DisOrder.
-# Copyright (C) 2005-2008 Richard Kettlewell
+# Copyright (C) 2005-2009 Richard Kettlewell
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
query.svg queryon.svg speaker.svg speakeron.svg cross32.png \
pause32.png play32.png playdisabled32.png playenabled32.png \
randomdisabled32.png randomenabled32.png rtpdisabled32.png \
-rtpenabled32.png duck55.png
+rtpenabled32.png duck55.png cards24.png cards48.png \
+cards-simple-fanned.svg cards-thin.svg
CLEANFILES=$(SEDFILES)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ version="1.0"
+ sodipodi:docname="cards-simple-fanned.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/richard/cards/cards-simple-fanned-24.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="17.25"
+ inkscape:cx="24"
+ inkscape:cy="24"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-bbox="true"
+ inkscape:snap-nodes="false"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:window-width="1301"
+ inkscape:window-height="1034"
+ inkscape:window-x="122"
+ inkscape:window-y="20">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2383"
+ visible="true"
+ enabled="true"
+ empspacing="8" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g3227">
+ <rect
+ transform="matrix(0.9659258,-0.2588191,0.2588191,0.9659258,0,0)"
+ y="8.3028555"
+ x="1.4500779"
+ height="34.000004"
+ width="24.000002"
+ id="rect3292"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.00000024;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="matrix(0.9659258,-0.2588191,0.2588191,0.9659258,0,0)"
+ y="9.3028555"
+ x="2.450078"
+ height="32.000004"
+ width="22.000002"
+ id="rect3294"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.00000023999999987;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="matrix(0.9659258,-0.2588191,0.2588191,0.9659258,0,0)"
+ y="13.302856"
+ x="6.4500785"
+ height="24.000002"
+ width="14.000001"
+ id="rect3296"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:2.00000023999999987;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ <g
+ id="g3222">
+ <rect
+ y="6.5112176"
+ x="12.457951"
+ height="34"
+ width="24"
+ id="rect3267"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="7.5112176"
+ x="13.457951"
+ height="32"
+ width="22"
+ id="rect2387"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="11.511218"
+ x="17.457951"
+ height="24"
+ width="14"
+ id="rect3159"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ <g
+ id="g3217">
+ <rect
+ transform="matrix(0.9659258,0.2588191,-0.2588191,0.9659258,0,0)"
+ y="1.7532461"
+ x="22.488214"
+ height="34.000004"
+ width="24.000002"
+ id="rect3276"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.00000024;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="matrix(0.9659258,0.2588191,-0.2588191,0.9659258,0,0)"
+ y="2.7532461"
+ x="23.488214"
+ height="32.000004"
+ width="22.000002"
+ id="rect3278"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.00000023999999987;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="matrix(0.9659258,0.2588191,-0.2588191,0.9659258,0,0)"
+ y="6.7532463"
+ x="27.488214"
+ height="24.000002"
+ width="14.000001"
+ id="rect3280"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:2.00000023999999987;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ version="1.0"
+ sodipodi:docname="cards-thin.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/richard/cards48.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="17.1875"
+ inkscape:cx="24"
+ inkscape:cy="24"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-bbox="true"
+ inkscape:snap-nodes="false"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:window-width="1639"
+ inkscape:window-height="1031"
+ inkscape:window-x="122"
+ inkscape:window-y="20">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2383"
+ visible="true"
+ enabled="true"
+ empspacing="8" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g3290"
+ transform="matrix(0.9848078,-0.1736482,0.1736482,0.9848078,3.6830881,3.8942155)">
+ <rect
+ y="2"
+ x="2"
+ height="34"
+ width="24"
+ id="rect3292"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="3"
+ x="3"
+ height="32"
+ width="22"
+ id="rect3294"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="7"
+ x="7"
+ height="24"
+ width="14"
+ id="rect3296"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ <g
+ id="g3269"
+ transform="translate(10,3)">
+ <rect
+ y="2"
+ x="2"
+ height="34"
+ width="24"
+ id="rect3267"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="3"
+ x="3"
+ height="32"
+ width="22"
+ id="rect2387"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="7"
+ x="7"
+ height="24"
+ width="14"
+ id="rect3159"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ <g
+ id="g3274"
+ transform="matrix(0.9848078,0.1736482,-0.1736482,0.9848078,16.28172,3.0320659)">
+ <rect
+ y="2"
+ x="2"
+ height="34"
+ width="24"
+ id="rect3276"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="3"
+ x="3"
+ height="32"
+ width="22"
+ id="rect3278"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="7"
+ x="7"
+ height="24"
+ width="14"
+ id="rect3280"
+ style="fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>