Merge pull request #93 from gergelypolonkai/chart-preview

Generate preview images for the charts in the list view
This commit is contained in:
Gergely Polonkai 2014-09-28 01:33:24 +02:00
commit 96a05a2933
10 changed files with 448 additions and 134 deletions

View File

@ -41,6 +41,7 @@ struct _AgChartRenderer
}; };
#define AG_CHART_RENDERER_TILE_SIZE 256 #define AG_CHART_RENDERER_TILE_SIZE 256
#define AG_CHART_RENDERER_ICON_SIZE 15
#define AG_CHART_RENDERER_CHECK_ICON_SIZE 40 #define AG_CHART_RENDERER_CHECK_ICON_SIZE 40
#define AG_CHART_RENDERER_TILE_MARGIN AG_CHART_RENDERER_CHECK_ICON_SIZE / 4 #define AG_CHART_RENDERER_TILE_MARGIN AG_CHART_RENDERER_CHECK_ICON_SIZE / 4
#define AG_CHART_RENDERER_TILE_MARGIN_BOTTOM AG_CHART_RENDERER_CHECK_ICON_SIZE / 8 #define AG_CHART_RENDERER_TILE_MARGIN_BOTTOM AG_CHART_RENDERER_CHECK_ICON_SIZE / 8

View File

@ -245,28 +245,30 @@ ag_chart_finalize(GObject *gobject)
} }
void void
ag_chart_add_planets(AgChart *chart) ag_chart_add_planets(AgChart *chart,
const GswePlanet *planets,
guint planet_count)
{ {
int i; int i;
AgChartPrivate *priv = ag_chart_get_instance_private(chart); AgChartPrivate *priv = ag_chart_get_instance_private(chart);
for (i = 0; i < used_planets_count; i++) { for (i = 0; i < planet_count; i++) {
gswe_moment_add_planet(GSWE_MOMENT(chart), used_planets[i], NULL); gswe_moment_add_planet(GSWE_MOMENT(chart), planets[i], NULL);
priv->planet_list = g_list_prepend( priv->planet_list = g_list_prepend(
priv->planet_list, priv->planet_list,
GINT_TO_POINTER(used_planets[i]) GINT_TO_POINTER(planets[i])
); );
} }
priv->planet_list = g_list_reverse(priv->planet_list); priv->planet_list = g_list_reverse(priv->planet_list);
} }
AgChart * static AgChart *
ag_chart_new_full(GsweTimestamp *timestamp, ag_chart_new_generic(GsweTimestamp *timestamp,
gdouble longitude, gdouble longitude,
gdouble latitude, gdouble latitude,
gdouble altitude, gdouble altitude,
GsweHouseSystem house_system) GsweHouseSystem house_system)
{ {
AgChart *chart; AgChart *chart;
GsweCoordinates *coords = g_new0(GsweCoordinates, 1); GsweCoordinates *coords = g_new0(GsweCoordinates, 1);
@ -283,7 +285,52 @@ ag_chart_new_full(GsweTimestamp *timestamp,
g_free(coords); g_free(coords);
ag_chart_add_planets(chart); return chart;
}
AgChart *
ag_chart_new_full(GsweTimestamp *timestamp,
gdouble longitude,
gdouble latitude,
gdouble altitude,
GsweHouseSystem house_system)
{
AgChart *chart = ag_chart_new_generic(
timestamp,
longitude,
latitude,
altitude,
house_system
);
ag_chart_add_planets(chart, used_planets, used_planets_count);
return chart;
}
AgChart *
ag_chart_new_preview(GsweTimestamp *timestamp,
gdouble longitude,
gdouble latitude,
gdouble altitude,
GsweHouseSystem house_system)
{
static const GswePlanet planets[] = {
GSWE_PLANET_SUN,
GSWE_PLANET_ASCENDANT,
GSWE_PLANET_MC
};
static const gint planet_count = sizeof(planets) / sizeof(GswePlanet);
AgChart *chart = ag_chart_new_generic(
timestamp,
longitude,
latitude,
altitude,
house_system
);
ag_chart_add_planets(chart, planets, planet_count);
return chart; return chart;
} }
@ -1176,12 +1223,12 @@ AgChart *ag_chart_load_from_placidus_file(GFile *file,
} }
AgChart * AgChart *
ag_chart_new_from_db_save(AgDbChartSave *save_data, GError **err) ag_chart_new_from_db_save(AgDbChartSave *save_data,
gboolean preview,
GError **err)
{ {
GsweTimestamp *timestamp; GsweTimestamp *timestamp;
gchar *house_system_enum_name; gchar *house_system_enum_name;
GTypeClass *house_system_class;
GEnumValue *enum_value;
GsweHouseSystem house_system; GsweHouseSystem house_system;
AgChart *chart; AgChart *chart;
@ -1196,40 +1243,32 @@ ag_chart_new_from_db_save(AgDbChartSave *save_data, GError **err)
} }
house_system_enum_name = g_utf8_strdown(save_data->house_system, -1); house_system_enum_name = g_utf8_strdown(save_data->house_system, -1);
house_system_class = g_type_class_ref(GSWE_TYPE_HOUSE_SYSTEM); house_system = ag_house_system_nick_to_id(house_system_enum_name);
if ((enum_value = g_enum_get_value_by_nick(
G_ENUM_CLASS(house_system_class),
house_system_enum_name
)) == NULL) {
g_free(house_system_enum_name);
g_set_error(
err,
AG_CHART_ERROR, AG_CHART_ERROR_INVALID_HOUSE_SYSTEM,
"Invalid house system: '%s'",
save_data->house_system
);
return NULL;
}
g_free(house_system_enum_name); g_free(house_system_enum_name);
house_system = enum_value->value;
timestamp = gswe_timestamp_new_from_gregorian_full( timestamp = gswe_timestamp_new_from_gregorian_full(
save_data->year, save_data->month, save_data->day, save_data->year, save_data->month, save_data->day,
save_data->hour, save_data->minute, save_data->second, 0, save_data->hour, save_data->minute, save_data->second, 0,
save_data->timezone save_data->timezone
); );
chart = ag_chart_new_full( if (preview) {
timestamp, chart = ag_chart_new_preview(
save_data->longitude, timestamp,
save_data->latitude, save_data->longitude,
save_data->altitude, save_data->latitude,
house_system save_data->altitude,
); house_system
);
} else {
chart = ag_chart_new_full(
timestamp,
save_data->longitude,
save_data->latitude,
save_data->altitude,
house_system
);
}
ag_chart_set_name(chart, save_data->name); ag_chart_set_name(chart, save_data->name);
ag_chart_set_country(chart, save_data->country); ag_chart_set_country(chart, save_data->country);
@ -1417,6 +1456,8 @@ ag_chart_create_svg(AgChart *chart,
gsize *length, gsize *length,
gboolean rendering, gboolean rendering,
AgDisplayTheme *theme, AgDisplayTheme *theme,
guint image_size,
guint icon_size,
GError **err) GError **err)
{ {
xmlDocPtr doc = create_save_doc(chart), xmlDocPtr doc = create_save_doc(chart),
@ -1754,13 +1795,26 @@ ag_chart_create_svg(AgChart *chart,
return NULL; return NULL;
} }
params = g_new0(gchar *, 5); params = g_new0(gchar *, 11);
params[0] = "rendering"; params[0] = "rendering";
params[1] = (rendering) ? "'yes'" : "'no'"; params[1] = (rendering) ? "'yes'" : "'no'";
params[2] = "additional-css"; params[2] = "additional-css";
css = ag_display_theme_to_css(theme); css = ag_display_theme_to_css(theme);
params[3] = g_strdup_printf("\"%s\"", css); params[3] = g_strdup_printf("\"%s\"", css);
g_free(css); g_free(css);
params[4] = "chart-size";
params[6] = "image-size";
params[8] = "icon-size";
if (image_size == 0) {
params[5] = g_strdup_printf("%d", AG_CHART_DEFAULT_RING_SIZE);
params[7] = g_strdup("0");
params[9] = g_strdup("0");
} else {
params[5] = g_strdup("0");
params[7] = g_strdup_printf("%d", image_size);
params[9] = g_strdup_printf("%d", icon_size);
}
// libxml2 messes up the output, as it prints decimal floating point // libxml2 messes up the output, as it prints decimal floating point
// numbers in a localized format. It is not good in locales that use a // numbers in a localized format. It is not good in locales that use a
@ -1774,6 +1828,9 @@ ag_chart_create_svg(AgChart *chart,
xsltFreeStylesheet(xslt_proc); xsltFreeStylesheet(xslt_proc);
xmlFreeDoc(doc); xmlFreeDoc(doc);
g_free(params[3]); g_free(params[3]);
g_free(params[5]);
g_free(params[7]);
g_free(params[9]);
g_free(params); g_free(params);
// Now, svg_doc contains the generated SVG file // Now, svg_doc contains the generated SVG file
@ -1811,7 +1868,14 @@ ag_chart_export_svg_to_file(AgChart *chart,
gchar *svg; gchar *svg;
gsize length; gsize length;
if ((svg = ag_chart_create_svg(chart, &length, TRUE, theme, err)) == NULL) { if ((svg = ag_chart_create_svg(
chart,
&length,
TRUE,
theme,
0, 0,
err
)) == NULL) {
return; return;
} }
@ -1828,16 +1892,15 @@ ag_chart_export_svg_to_file(AgChart *chart,
); );
} }
void GdkPixbuf *
ag_chart_export_jpg_to_file(AgChart *chart, ag_chart_get_pixbuf(AgChart *chart,
GFile *file, guint image_size,
AgDisplayTheme *theme, guint icon_size,
GError **err) AgDisplayTheme *theme,
GError **err)
{ {
gchar *svg, gchar *svg;
*jpg; gsize svg_length;
gsize svg_length,
jpg_length;
RsvgHandle *svg_handle; RsvgHandle *svg_handle;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
@ -1846,19 +1909,21 @@ ag_chart_export_jpg_to_file(AgChart *chart,
&svg_length, &svg_length,
TRUE, TRUE,
theme, theme,
image_size,
icon_size,
err err
)) == NULL) { )) == NULL) {
return; return NULL;
} }
if ((svg_handle = rsvg_handle_new_from_data( if ((svg_handle = rsvg_handle_new_from_data(
(const guint8 *)svg, (const guint8 *)svg,
svg_length, svg_length,
err err
)) == NULL) { )) == NULL) {
g_free(svg); g_free(svg);
return; return NULL;
} }
g_free(svg); g_free(svg);
@ -1870,6 +1935,25 @@ ag_chart_export_jpg_to_file(AgChart *chart,
_("Unknown rendering error") _("Unknown rendering error")
); );
return NULL;
}
return pixbuf;
}
void
ag_chart_export_jpg_to_file(AgChart *chart,
GFile *file,
AgDisplayTheme *theme,
GError **err)
{
gchar *jpg;
gsize jpg_length;
GdkPixbuf *pixbuf;
pixbuf = ag_chart_get_pixbuf(chart, 0, 0, theme, err);
if (pixbuf == NULL) {
return; return;
} }
@ -1926,7 +2010,7 @@ ag_chart_get_db_save(AgChart *chart, gint db_id)
{ {
GsweCoordinates *coords; GsweCoordinates *coords;
AgChartPrivate *priv = ag_chart_get_instance_private(chart); AgChartPrivate *priv = ag_chart_get_instance_private(chart);
AgDbChartSave *save_data = ag_db_chart_save_new(); AgDbChartSave *save_data = ag_db_chart_save_new(TRUE);
GsweTimestamp *timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(chart)); GsweTimestamp *timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(chart));
GEnumClass *house_system_class; GEnumClass *house_system_class;
GEnumValue *house_system_enum; GEnumValue *house_system_enum;

View File

@ -22,10 +22,14 @@
#include <glib-object.h> #include <glib-object.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <swe-glib.h> #include <swe-glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "ag-db.h" #include "ag-db.h"
#include "ag-display-theme.h" #include "ag-display-theme.h"
#define AG_CHART_DEFAULT_RING_SIZE 600
#define AG_CHART_DEFAULT_ICON_SIZE 30
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum { typedef enum {
@ -63,7 +67,10 @@ struct _AgChartClass {
GsweMomentClass parent_class; GsweMomentClass parent_class;
}; };
typedef void (*AgChartSaveImageFunc)(AgChart *, GFile *, AgDisplayTheme *, GError **); typedef void (*AgChartSaveImageFunc)(AgChart *,
GFile *,
AgDisplayTheme *,
GError **);
GType ag_chart_get_type(void) G_GNUC_CONST; GType ag_chart_get_type(void) G_GNUC_CONST;
@ -73,13 +80,21 @@ AgChart *ag_chart_new_full(GsweTimestamp *timestamp,
gdouble altitude, gdouble altitude,
GsweHouseSystem house_system); GsweHouseSystem house_system);
AgChart *ag_chart_new_preview(GsweTimestamp *timestamp,
gdouble longitude,
gdouble latitude,
gdouble altitude,
GsweHouseSystem house_system);
AgChart *ag_chart_load_from_agc(GFile *file, AgChart *ag_chart_load_from_agc(GFile *file,
GError **err); GError **err);
AgChart *ag_chart_load_from_placidus_file(GFile *file, AgChart *ag_chart_load_from_placidus_file(GFile *file,
GError **err); GError **err);
AgChart *ag_chart_new_from_db_save(AgDbChartSave *save_data, GError **err); AgChart *ag_chart_new_from_db_save(AgDbChartSave *save_data,
gboolean preview,
GError **err);
void ag_chart_save_to_file(AgChart *chart, void ag_chart_save_to_file(AgChart *chart,
GFile *file, GFile *file,
@ -114,6 +129,8 @@ gchar *ag_chart_create_svg(AgChart *chart,
gsize *length, gsize *length,
gboolean rendering, gboolean rendering,
AgDisplayTheme *theme, AgDisplayTheme *theme,
guint image_size,
guint icon_size,
GError **err); GError **err);
GList *ag_chart_get_planets(AgChart *chart); GList *ag_chart_get_planets(AgChart *chart);
@ -124,6 +141,12 @@ const gchar *ag_chart_get_note(AgChart *chart);
AgDbChartSave *ag_chart_get_db_save(AgChart *chart, gint db_id); AgDbChartSave *ag_chart_get_db_save(AgChart *chart, gint db_id);
GdkPixbuf *ag_chart_get_pixbuf(AgChart *chart,
guint image_size,
guint icon_size,
AgDisplayTheme *theme,
GError **err);
#define AG_CHART_ERROR (ag_chart_error_quark()) #define AG_CHART_ERROR (ag_chart_error_quark())
GQuark ag_chart_error_quark(void); GQuark ag_chart_error_quark(void);

View File

@ -659,6 +659,14 @@ ag_db_chart_save(AgDb *db, AgDbChartSave *save_data, GError **err)
note = G_VALUE_INIT; note = G_VALUE_INIT;
AgDbPrivate *priv = ag_db_get_instance_private(db); AgDbPrivate *priv = ag_db_get_instance_private(db);
if (save_data == NULL) {
g_error("Trying to save a NULL chart!");
}
if (!save_data->populated) {
g_error("Only populated chart data can be saved!");
}
g_value_init(&name, G_TYPE_STRING); g_value_init(&name, G_TYPE_STRING);
g_value_set_string(&name, save_data->name); g_value_set_string(&name, save_data->name);
@ -828,12 +836,13 @@ ag_db_chart_save(AgDb *db, AgDbChartSave *save_data, GError **err)
} }
AgDbChartSave * AgDbChartSave *
ag_db_chart_save_new(void) ag_db_chart_save_new(gboolean populated)
{ {
AgDbChartSave *save_data; AgDbChartSave *save_data;
save_data = g_new0(AgDbChartSave, 1); save_data = g_new0(AgDbChartSave, 1);
save_data->refcount = 1; save_data->refcount = 1;
save_data->populated = populated;
return save_data; return save_data;
} }
@ -874,7 +883,7 @@ ag_db_chart_get_list(AgDb *db, GError **err)
while (gda_data_model_iter_move_next(iter)) { while (gda_data_model_iter_move_next(iter)) {
const GValue *value; const GValue *value;
AgDbChartSave *save_data = ag_db_chart_save_new(); AgDbChartSave *save_data = ag_db_chart_save_new(FALSE);
value = gda_data_model_iter_get_value_at(iter, 0); value = gda_data_model_iter_get_value_at(iter, 0);
save_data->db_id = g_value_get_int(value); save_data->db_id = g_value_get_int(value);
@ -951,7 +960,7 @@ ag_db_chart_get_data_by_id(AgDb *db, guint row_id, GError **err)
return NULL; return NULL;
} }
save_data = ag_db_chart_save_new(); save_data = ag_db_chart_save_new(TRUE);
/* id */ /* id */
value = gda_data_model_get_value_at( value = gda_data_model_get_value_at(

View File

@ -50,6 +50,7 @@ struct _AgDbClass {
typedef struct _AgDbChartSave { typedef struct _AgDbChartSave {
gint db_id; gint db_id;
gboolean populated;
gchar *name; gchar *name;
gchar *country; gchar *country;
gchar *city; gchar *city;
@ -84,7 +85,7 @@ gboolean ag_db_chart_save(AgDb *db,
AgDbChartSave *save_data, AgDbChartSave *save_data,
GError **err); GError **err);
AgDbChartSave *ag_db_chart_save_new(void); AgDbChartSave *ag_db_chart_save_new(gboolean populated);
AgDbChartSave *ag_db_chart_save_ref(AgDbChartSave *save_data); AgDbChartSave *ag_db_chart_save_ref(AgDbChartSave *save_data);

View File

@ -35,6 +35,8 @@ static gchar *builtin_theme_name[AG_DISPLAY_THEME_COUNT] = {
NC_("Display theme name", "No comets"), NC_("Display theme name", "No comets"),
}; };
static AgDisplayTheme *preview_theme = NULL;
gchar * gchar *
ag_display_theme_to_css(AgDisplayTheme *theme) ag_display_theme_to_css(AgDisplayTheme *theme)
{ {
@ -337,3 +339,27 @@ ag_display_theme_free(AgDisplayTheme *display_theme)
g_list_free(display_theme->antiscia); g_list_free(display_theme->antiscia);
g_free(display_theme); g_free(display_theme);
} }
AgDisplayTheme *
ag_display_theme_get_preview_theme(void)
{
if (!preview_theme) {
preview_theme = g_new0(AgDisplayTheme, 1);
preview_theme->id = 0;
preview_theme->name = "Preview theme";
preview_theme->builtin = TRUE;
preview_theme->planets_include = TRUE;
preview_theme->planets = NULL;
preview_theme->aspects_include = TRUE;
preview_theme->aspects = NULL;
preview_theme->antiscia_include = TRUE;
preview_theme->antiscia = NULL;
preview_theme->planets = g_list_prepend(
preview_theme->planets,
GINT_TO_POINTER(GSWE_PLANET_SUN)
);
}
return preview_theme;
}

View File

@ -49,4 +49,6 @@ GList *ag_display_theme_get_list(void);
void ag_display_theme_free(AgDisplayTheme *display_theme); void ag_display_theme_free(AgDisplayTheme *display_theme);
AgDisplayTheme *ag_display_theme_get_preview_theme(void);
#endif /* __AG_DISPLAY_THEME_H__ */ #endif /* __AG_DISPLAY_THEME_H__ */

View File

@ -1,7 +1,11 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "ag-enumtypes.h" #include "ag-enumtypes.h"
#include "ag-icon-view.h" #include "ag-icon-view.h"
#include "ag-db.h" #include "ag-db.h"
#include "ag-chart-renderer.h" #include "ag-chart-renderer.h"
#include "ag-display-theme.h"
#include "ag-chart.h"
typedef struct _AgIconViewPrivate { typedef struct _AgIconViewPrivate {
AgIconViewMode mode; AgIconViewMode mode;
@ -19,6 +23,7 @@ enum {
enum { enum {
AG_ICON_VIEW_COLUMN_SELECTED, AG_ICON_VIEW_COLUMN_SELECTED,
AG_ICON_VIEW_COLUMN_ITEM, AG_ICON_VIEW_COLUMN_ITEM,
AG_ICON_VIEW_COLUMN_PIXBUF,
AG_ICON_VIEW_COLUMN_COLUMNS AG_ICON_VIEW_COLUMN_COLUMNS
}; };
@ -38,7 +43,10 @@ ag_icon_view_set_mode(AgIconView *icon_view, AgIconViewMode mode)
ag_icon_view_unselect_all(icon_view); ag_icon_view_unselect_all(icon_view);
} }
ag_chart_renderer_set_toggle_visible(priv->thumb_renderer, (mode == AG_ICON_VIEW_MODE_SELECTION)); ag_chart_renderer_set_toggle_visible(
priv->thumb_renderer,
(mode == AG_ICON_VIEW_MODE_SELECTION)
);
gtk_widget_queue_draw(GTK_WIDGET(icon_view)); gtk_widget_queue_draw(GTK_WIDGET(icon_view));
@ -122,12 +130,18 @@ ag_icon_view_button_press_event_cb(GtkWidget *widget,
GtkIconView *gtk_icon_view = GTK_ICON_VIEW(widget); GtkIconView *gtk_icon_view = GTK_ICON_VIEW(widget);
AgIconView *ag_icon_view = AG_ICON_VIEW(widget); AgIconView *ag_icon_view = AG_ICON_VIEW(widget);
path = gtk_icon_view_get_path_at_pos(gtk_icon_view, ((GdkEventButton *)event)->x, ((GdkEventButton *)event)->y); path = gtk_icon_view_get_path_at_pos(
gtk_icon_view,
((GdkEventButton *)event)->x,
((GdkEventButton *)event)->y
);
if (path != NULL) { if (path != NULL) {
gboolean selected; gboolean selected;
AgDbChartSave *chart_save; AgDbChartSave *chart_save;
GtkListStore *store = GTK_LIST_STORE(gtk_icon_view_get_model(gtk_icon_view)); GtkListStore *store = GTK_LIST_STORE(gtk_icon_view_get_model(
gtk_icon_view)
);
if (event->button == GDK_BUTTON_SECONDARY) { if (event->button == GDK_BUTTON_SECONDARY) {
ag_icon_view_set_mode(ag_icon_view, AG_ICON_VIEW_MODE_SELECTION); ag_icon_view_set_mode(ag_icon_view, AG_ICON_VIEW_MODE_SELECTION);
@ -137,9 +151,18 @@ ag_icon_view_button_press_event_cb(GtkWidget *widget,
GtkTreeIter iter; GtkTreeIter iter;
if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) { if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) {
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, AG_ICON_VIEW_COLUMN_SELECTED, &selected, AG_ICON_VIEW_COLUMN_ITEM, &chart_save, -1); gtk_tree_model_get(
GTK_TREE_MODEL(store), &iter,
AG_ICON_VIEW_COLUMN_SELECTED, &selected,
AG_ICON_VIEW_COLUMN_ITEM, &chart_save,
-1
);
gtk_list_store_set(store, &iter, AG_ICON_VIEW_COLUMN_SELECTED, !selected, -1); gtk_list_store_set(
store, &iter,
AG_ICON_VIEW_COLUMN_SELECTED, !selected,
-1
);
ag_icon_view_selection_changed(ag_icon_view); ag_icon_view_selection_changed(ag_icon_view);
} }
@ -180,22 +203,6 @@ ag_icon_view_class_init(AgIconViewClass *klass)
); );
} }
static void
ag_icon_view_chart_renderer_func(GtkCellLayout *layout,
GtkCellRenderer *renderer,
GtkTreeModel *model,
GtkTreeIter *iter,
AgIconView *icon_view)
{
AgDbChartSave *chart_save;
gtk_tree_model_get(model, iter, AG_ICON_VIEW_COLUMN_ITEM, &chart_save, -1);
if (chart_save) {
g_object_set(renderer, "pixbuf", NULL, NULL);
}
}
static void static void
ag_icon_view_text_renderer_func(GtkCellLayout *layout, ag_icon_view_text_renderer_func(GtkCellLayout *layout,
GtkCellRenderer *renderer, GtkCellRenderer *renderer,
@ -226,7 +233,8 @@ ag_icon_view_init(AgIconView *icon_view)
priv->model = gtk_list_store_new( priv->model = gtk_list_store_new(
AG_ICON_VIEW_COLUMN_COLUMNS, AG_ICON_VIEW_COLUMN_COLUMNS,
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
AG_TYPE_DB_CHART_SAVE AG_TYPE_DB_CHART_SAVE,
GDK_TYPE_PIXBUF
); );
gtk_icon_view_set_model( gtk_icon_view_set_model(
GTK_ICON_VIEW(icon_view), GTK_ICON_VIEW(icon_view),
@ -267,6 +275,12 @@ ag_icon_view_init(AgIconView *icon_view)
GTK_CELL_RENDERER(priv->thumb_renderer), GTK_CELL_RENDERER(priv->thumb_renderer),
"checked", AG_ICON_VIEW_COLUMN_SELECTED "checked", AG_ICON_VIEW_COLUMN_SELECTED
); );
gtk_cell_layout_add_attribute(
GTK_CELL_LAYOUT(icon_view),
GTK_CELL_RENDERER(priv->thumb_renderer),
"pixbuf", AG_ICON_VIEW_COLUMN_PIXBUF
);
/*
gtk_cell_layout_set_cell_data_func( gtk_cell_layout_set_cell_data_func(
GTK_CELL_LAYOUT(icon_view), GTK_CELL_LAYOUT(icon_view),
GTK_CELL_RENDERER(priv->thumb_renderer), GTK_CELL_RENDERER(priv->thumb_renderer),
@ -274,6 +288,7 @@ ag_icon_view_init(AgIconView *icon_view)
icon_view, icon_view,
NULL NULL
); );
*/
priv->text_renderer = gtk_cell_renderer_text_new(); priv->text_renderer = gtk_cell_renderer_text_new();
gtk_cell_renderer_set_alignment( gtk_cell_renderer_set_alignment(
@ -298,15 +313,49 @@ void
ag_icon_view_add_chart(AgIconView *icon_view, AgDbChartSave *chart_save) ag_icon_view_add_chart(AgIconView *icon_view, AgDbChartSave *chart_save)
{ {
GtkTreeIter iter; GtkTreeIter iter;
AgIconViewPrivate *priv = ag_icon_view_get_instance_private(icon_view); AgChart *chart;
AgIconViewPrivate *priv = ag_icon_view_get_instance_private(icon_view);
AgDisplayTheme *theme = ag_display_theme_get_preview_theme();
AgDbChartSave *save_data = chart_save;
AgDb *db = ag_db_get();
GdkPixbuf *pixbuf = NULL;
g_debug("Adding chart for %s", chart_save->name); g_debug("Adding chart for %s", chart_save->name);
if (!chart_save->populated) {
save_data = ag_db_chart_get_data_by_id(
db,
chart_save->db_id,
NULL
);
} else {
save_data = ag_db_chart_save_ref(chart_save);
}
g_object_unref(db);
chart = ag_chart_new_from_db_save(
save_data,
TRUE,
NULL
);
pixbuf = ag_chart_get_pixbuf(
chart,
AG_CHART_RENDERER_TILE_SIZE,
AG_CHART_RENDERER_ICON_SIZE,
theme,
NULL
);
g_object_unref(chart);
gtk_list_store_append(priv->model, &iter); gtk_list_store_append(priv->model, &iter);
gtk_list_store_set( gtk_list_store_set(
priv->model, &iter, priv->model, &iter,
AG_ICON_VIEW_COLUMN_SELECTED, FALSE, AG_ICON_VIEW_COLUMN_SELECTED, FALSE,
AG_ICON_VIEW_COLUMN_ITEM, chart_save, AG_ICON_VIEW_COLUMN_ITEM, save_data,
AG_ICON_VIEW_COLUMN_PIXBUF, pixbuf,
-1 -1
); );
} }

View File

@ -93,6 +93,22 @@ struct cc_search {
gchar *ret_code; gchar *ret_code;
}; };
enum {
PREVIEW_STATE_STARTED,
PREVIEW_STATE_LOADING,
PREVIEW_STATE_COMPLETE,
PREVIEW_STATE_FINISHED
};
typedef struct {
guint load_state;
guint load_id;
AgIconView *icon_view;
gint n_items;
gint n_loaded;
GList *items;
} LoadIdleData;
G_DEFINE_QUARK(ag_window_error_quark, ag_window_error); G_DEFINE_QUARK(ag_window_error_quark, ag_window_error);
G_DEFINE_TYPE_WITH_PRIVATE(AgWindow, ag_window, GTK_TYPE_APPLICATION_WINDOW); G_DEFINE_TYPE_WITH_PRIVATE(AgWindow, ag_window, GTK_TYPE_APPLICATION_WINDOW);
@ -516,6 +532,7 @@ ag_window_redraw_chart(AgWindow *window)
&length, &length,
FALSE, FALSE,
NULL, NULL,
0, 0,
&err &err
); );
@ -719,7 +736,7 @@ ag_window_recalculate_chart(AgWindow *window, gboolean set_everything)
gtk_spin_button_update(GTK_SPIN_BUTTON(current)); gtk_spin_button_update(GTK_SPIN_BUTTON(current));
} }
edit_data = ag_db_chart_save_new(); edit_data = ag_db_chart_save_new(TRUE);
edit_data->db_id = db_id; edit_data->db_id = db_id;
@ -1950,6 +1967,7 @@ ag_window_list_item_activated_cb(AgIconView *icon_view,
if ((priv->chart = ag_chart_new_from_db_save( if ((priv->chart = ag_chart_new_from_db_save(
priv->saved_data, priv->saved_data,
FALSE,
&err &err
)) == NULL) { )) == NULL) {
ag_app_message_dialog( ag_app_message_dialog(
@ -2787,26 +2805,84 @@ ag_window_change_tab(AgWindow *window, const gchar *tab_name)
); );
} }
static void static gboolean
ag_window_add_chart_to_list(AgDbChartSave *save_data, AgWindow *window) ag_window_add_chart(LoadIdleData *idle_data)
{ {
AgWindowPrivate *priv = ag_window_get_instance_private(window); AgDbChartSave *save_data;
ag_icon_view_add_chart(AG_ICON_VIEW(priv->chart_list), save_data); g_assert(
(idle_data->load_state == PREVIEW_STATE_STARTED)
|| (idle_data->load_state == PREVIEW_STATE_LOADING)
);
if (!idle_data->items) {
idle_data->load_state = PREVIEW_STATE_COMPLETE;
return FALSE;
}
if (!idle_data->n_items) {
idle_data->n_items = g_list_length(idle_data->items);
idle_data->n_loaded = 0;
idle_data->load_state = PREVIEW_STATE_LOADING;
}
save_data = g_list_nth_data(idle_data->items, idle_data->n_loaded);
g_assert(save_data);
ag_icon_view_add_chart(idle_data->icon_view, save_data);
idle_data->n_loaded++;
// TODO: maybe a progress bar should update somewhere during loading?
if (idle_data->n_loaded == idle_data->n_items) {
idle_data->load_state = PREVIEW_STATE_COMPLETE;
idle_data->n_loaded = 0;
idle_data->n_items = 0;
g_list_free(idle_data->items);
idle_data->items = NULL;
return FALSE;
} else {
return TRUE;
}
}
static void
ag_window_cleanup_load_items(LoadIdleData *idle_data)
{
g_assert(idle_data->load_state == PREVIEW_STATE_COMPLETE);
g_free(idle_data);
} }
gboolean gboolean
ag_window_load_chart_list(AgWindow *window) ag_window_load_chart_list(AgWindow *window)
{ {
AgDb *db = ag_db_get(); LoadIdleData *idle_data;
GError *err = NULL; AgDb *db = ag_db_get();
GList *chart_list = ag_db_chart_get_list(db, &err); GError *err = NULL;
GList *chart_list = ag_db_chart_get_list(db, &err);
AgWindowPrivate *priv = ag_window_get_instance_private(window);
/* With only a few charts, this should be fine. Maybe implementing lazy /* Lazy loading of charts with previews. Idea is from
* loading would be a better idea. See: * http://blogs.gnome.org/ebassi/documentation/lazy-loading/ */
* http://blogs.gnome.org/ebassi/documentation/lazy-loading/
*/ idle_data = g_new(LoadIdleData, 1);
g_list_foreach(chart_list, (GFunc)ag_window_add_chart_to_list, window); idle_data->items = chart_list;
idle_data->n_items = 0;
idle_data->n_loaded = 0;
idle_data->icon_view = AG_ICON_VIEW(priv->chart_list);
idle_data->load_state = PREVIEW_STATE_STARTED;
idle_data->load_id = g_idle_add_full(
G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc)ag_window_add_chart,
idle_data,
(GDestroyNotify)ag_window_cleanup_load_items
);
return TRUE; return TRUE;
} }

View File

@ -15,13 +15,53 @@
<xsl:variable name="asc" select="chartinfo/ascmcs/ascendant/@degree_ut" /> <xsl:variable name="asc" select="chartinfo/ascmcs/ascendant/@degree_ut" />
<xsl:variable name="asc_rotate" select="$asc - 180"/> <xsl:variable name="asc_rotate" select="$asc - 180"/>
<xsl:variable name="PI" select="math:constant('PI', 10)" /> <xsl:variable name="PI" select="math:constant('PI', 10)" />
<xsl:variable name="chart_size" select="600" />
<xsl:variable name="icon_size" select="30" />
<xsl:variable name="max_dist" select="/chartinfo/bodies/body/@dist[not(. &lt; ../../body/@dist)][1]" /> <xsl:variable name="max_dist" select="/chartinfo/bodies/body/@dist[not(. &lt; ../../body/@dist)][1]" />
<xsl:variable name="image_size" select="$chart_size + 2.82 * $icon_size * ($max_dist + 2)" /> <xsl:variable name="loaded_icon_size" select="30" />
<xsl:variable name="r_aspect" select="$chart_size * 0.4" /> <xsl:variable name="icon_size">
<xsl:choose>
<xsl:when test="$icon-size != 0">
<xsl:value-of select="$icon-size"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$loaded_icon_size"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="icon_scale" select="$icon_size div $loaded_icon_size" />
<xsl:variable name="chart_size">
<xsl:choose>
<xsl:when test="$chart-size != 0">
<xsl:value-of select="$chart-size"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$image-size - 2.82 * $icon_size * ($max_dist + 2)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="image_size">
<xsl:choose>
<xsl:when test="$chart-size != 0">
<xsl:value-of select="$chart-size + 2.82 * $icon_size * ($max_dist + 2)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$image-size"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="r_outer" select="$chart_size * 0.5" />
<xsl:variable name="r_signs" select="$r_outer - ($icon_size * 1.5)" />
<xsl:variable name="r_aspect" select="$r_signs - ($icon_size * 0.5)" />
<xsl:variable name="r_houses" select="$chart_size * 0.116666" />
<xsl:variable name="r_moon" select="$chart_size * 0.083333" /> <xsl:variable name="r_moon" select="$chart_size * 0.083333" />
<xsl:variable name="sign_pos" select="$r_signs + ($icon_size * 0.25)" />
<xsl:variable name="deg_len" select="($r_signs - $r_aspect)" />
<xsl:variable name="deg5_len" select="$deg_len * 0.75" />
<xsl:variable name="deg1_len" select="$deg_len * 0.3" />
<xsl:variable name="planet_marker_len" select="$icon_size div 2" />
<xsl:template name="planet-template"> <xsl:template name="planet-template">
<xsl:param name="planet_name"/> <xsl:param name="planet_name"/>
<xsl:param name="planet_base"/> <xsl:param name="planet_base"/>
@ -35,22 +75,25 @@
<xsl:attribute name="class">planet planet-<xsl:value-of select="$planet_name"/></xsl:attribute> <xsl:attribute name="class">planet planet-<xsl:value-of select="$planet_name"/></xsl:attribute>
<xsl:attribute name="transform">rotate(<xsl:value-of select="-$rotate"/>, 0, 0)</xsl:attribute> <xsl:attribute name="transform">rotate(<xsl:value-of select="-$rotate"/>, 0, 0)</xsl:attribute>
<line y1="0" y2="0" class="planet-marker"> <line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$chart_size * 0.383333"/></xsl:attribute> <xsl:attribute name="x1"><xsl:value-of select="$r_aspect - $planet_marker_len"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$chart_size * 0.4"/></xsl:attribute> <xsl:attribute name="x2"><xsl:value-of select="$r_aspect"/></xsl:attribute>
</line> </line>
<line y1="0" y2="0" class="planet-marker"> <line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$chart_size * 0.5"/></xsl:attribute> <xsl:attribute name="x1"><xsl:value-of select="$r_outer"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$chart_size * 0.516666"/></xsl:attribute> <xsl:attribute name="x2"><xsl:value-of select="$r_outer + $planet_marker_len"/></xsl:attribute>
</line> </line>
<g> <g>
<xsl:attribute name="transform">translate(<xsl:value-of select="$chart_size * 0.55 + $dist * ($icon_size * 1.1666666)"/>, <xsl:value-of select="-$icon_size div 2"/>) rotate(<xsl:value-of select="$rotate - $asc_rotate"/>, <xsl:value-of select="$icon_size div 2"/>, <xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">translate(<xsl:value-of select="$chart_size * 0.55 + $dist * ($icon_size * 1.1666666)"/>, <xsl:value-of select="-$icon_size div 2"/>) rotate(<xsl:value-of select="$rotate - $asc_rotate"/>, <xsl:value-of select="$icon_size div 2"/>, <xsl:value-of select="$icon_size div 2"/>)</xsl:attribute>
<use class="planet-symbol"> <use class="planet-symbol">
<xsl:attribute name="xlink:href">#<xsl:value-of select="$planet_base"/>_tmpl</xsl:attribute> <xsl:attribute name="xlink:href">#<xsl:value-of select="$planet_base"/>_tmpl</xsl:attribute>
<xsl:choose> <xsl:attribute name="transform">
<xsl:when test="$upside-down='yes'"> <xsl:choose>
<xsl:attribute name="transform">rotate(180, <xsl:value-of select="$icon_size div 2"/>, <xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:when test="$upside-down='yes'">
</xsl:when> rotate(180, <xsl:value-of select="$icon_size div 2"/>, <xsl:value-of select="$icon_size div 2"/>)
</xsl:choose> </xsl:when>
</xsl:choose>
scale(<xsl:value-of select="$icon_scale" />)
</xsl:attribute>
</use> </use>
<xsl:choose> <xsl:choose>
<xsl:when test="$retrograde='True'"> <xsl:when test="$retrograde='True'">
@ -151,24 +194,24 @@
<xsl:attribute name="transform"><xsl:value-of select="concat('rotate(', $asc_rotate, ',0,0)')" /></xsl:attribute> <xsl:attribute name="transform"><xsl:value-of select="concat('rotate(', $asc_rotate, ',0,0)')" /></xsl:attribute>
<g id="base"> <g id="base">
<circle id="outer_circle" cx="0" cy="0" class="thick"> <circle id="outer_circle" cx="0" cy="0" class="thick">
<xsl:attribute name="r"><xsl:value-of select="$chart_size * 0.5"/></xsl:attribute> <xsl:attribute name="r"><xsl:value-of select="$r_outer"/></xsl:attribute>
</circle> </circle>
<circle id="middle_circle" cx="0" cy="0" class="thin"> <circle id="middle_circle" cx="0" cy="0" class="thin">
<xsl:attribute name="r"><xsl:value-of select="$chart_size * 0.425333"/></xsl:attribute> <xsl:attribute name="r"><xsl:value-of select="$r_signs"/></xsl:attribute>
</circle> </circle>
<circle id="inner_circle" cx="0" cy="0" class="thick"> <circle id="inner_circle" cx="0" cy="0" class="thick">
<xsl:attribute name="r"><xsl:value-of select="$r_aspect"/></xsl:attribute> <xsl:attribute name="r"><xsl:value-of select="$r_aspect"/></xsl:attribute>
</circle> </circle>
<circle id="house_circle" cx="0" cy="0" class="thin"> <circle id="house_circle" cx="0" cy="0" class="thin">
<xsl:attribute name="r"><xsl:value-of select="$chart_size * 0.116666"/></xsl:attribute> <xsl:attribute name="r"><xsl:value-of select="$r_houses"/></xsl:attribute>
</circle> </circle>
<circle id="moon_circle" cx="0" cy="0" class="thick" style="fill:#00000;stroke:none"> <circle id="moon_circle" cx="0" cy="0" class="thick" style="fill:#00000;stroke:none">
<xsl:attribute name="r"><xsl:value-of select="$r_moon"/></xsl:attribute> <xsl:attribute name="r"><xsl:value-of select="$r_moon"/></xsl:attribute>
</circle> </circle>
<line id="aries_start" y1="0" y2="0" class="degree-thick"> <line id="aries_start" y1="0" y2="0" class="degree-thick">
<xsl:attribute name="x1"><xsl:value-of select="$chart_size * 0.4"/></xsl:attribute> <xsl:attribute name="x1"><xsl:value-of select="$r_aspect"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$chart_size * 0.5"/></xsl:attribute> <xsl:attribute name="x2"><xsl:value-of select="$r_outer"/></xsl:attribute>
</line> </line>
<use x="0" y="0" xlink:href="#aries_start" id="taurus_start" transform="rotate(-30,0,0)" class="degree-thick" /> <use x="0" y="0" xlink:href="#aries_start" id="taurus_start" transform="rotate(-30,0,0)" class="degree-thick" />
<use x="0" y="0" xlink:href="#aries_start" id="gemini_start" transform="rotate(-60,0,0)" class="degree-thick" /> <use x="0" y="0" xlink:href="#aries_start" id="gemini_start" transform="rotate(-60,0,0)" class="degree-thick" />
@ -183,8 +226,8 @@
<use x="0" y="0" xlink:href="#aries_start" id="pisces_start" transform="rotate(-330,0,0)" class="degree-thick" /> <use x="0" y="0" xlink:href="#aries_start" id="pisces_start" transform="rotate(-330,0,0)" class="degree-thick" />
<line id="deg_10" y1="0" y2="0" transform="rotate(-10,0,0)" class="degree-thin"> <line id="deg_10" y1="0" y2="0" transform="rotate(-10,0,0)" class="degree-thin">
<xsl:attribute name="x1"><xsl:value-of select="$chart_size * 0.4"/></xsl:attribute> <xsl:attribute name="x1"><xsl:value-of select="$r_aspect"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$chart_size * 0.425"/></xsl:attribute> <xsl:attribute name="x2"><xsl:value-of select="$r_signs"/></xsl:attribute>
</line> </line>
<use x="0" y="0" xlink:href="#deg_10" id="deg_20" transform="rotate(-10,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_10" id="deg_20" transform="rotate(-10,0,0)" class="degree-thin" />
<use x="0" y="0" xlink:href="#deg_10" id="deg_40" transform="rotate(-30,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_10" id="deg_40" transform="rotate(-30,0,0)" class="degree-thin" />
@ -211,8 +254,8 @@
<use x="0" y="0" xlink:href="#deg_10" id="deg_350" transform="rotate(-340,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_10" id="deg_350" transform="rotate(-340,0,0)" class="degree-thin" />
<line id="deg_5" y1="0" y2="0" transform="rotate(-5,0,0)" class="degree-thin"> <line id="deg_5" y1="0" y2="0" transform="rotate(-5,0,0)" class="degree-thin">
<xsl:attribute name="x1"><xsl:value-of select="$chart_size * 0.4"/></xsl:attribute> <xsl:attribute name="x1"><xsl:value-of select="$r_aspect"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$chart_size * 0.416666"/></xsl:attribute> <xsl:attribute name="x2"><xsl:value-of select="$r_aspect + $deg5_len"/></xsl:attribute>
</line> </line>
<use x="0" y="0" xlink:href="#deg_5" id="deg_15" transform="rotate(-10,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_5" id="deg_15" transform="rotate(-10,0,0)" class="degree-thin" />
<use x="0" y="0" xlink:href="#deg_5" id="deg_25" transform="rotate(-20,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_5" id="deg_25" transform="rotate(-20,0,0)" class="degree-thin" />
@ -251,8 +294,8 @@
<use x="0" y="0" xlink:href="#deg_5" id="deg_355" transform="rotate(-350,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_5" id="deg_355" transform="rotate(-350,0,0)" class="degree-thin" />
<line id="deg_1" y1="0" y2="0" transform="rotate(-1,0,0)" class="degree-thin"> <line id="deg_1" y1="0" y2="0" transform="rotate(-1,0,0)" class="degree-thin">
<xsl:attribute name="x1"><xsl:value-of select="$chart_size * 0.4"/></xsl:attribute> <xsl:attribute name="x1"><xsl:value-of select="$r_aspect"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$chart_size * 0.408333"/></xsl:attribute> <xsl:attribute name="x2"><xsl:value-of select="$r_aspect + $deg1_len"/></xsl:attribute>
</line> </line>
<use x="0" y="0" xlink:href="#deg_1" id="deg_2" transform="rotate(-1,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_1" id="deg_2" transform="rotate(-1,0,0)" class="degree-thin" />
<use x="0" y="0" xlink:href="#deg_1" id="deg_3" transform="rotate(-2,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_1" id="deg_3" transform="rotate(-2,0,0)" class="degree-thin" />
@ -543,40 +586,40 @@
<use x="0" y="0" xlink:href="#deg_1" id="deg_359" transform="rotate(-358,0,0)" class="degree-thin" /> <use x="0" y="0" xlink:href="#deg_1" id="deg_359" transform="rotate(-358,0,0)" class="degree-thin" />
<use x="0" y="0" xlink:href="#sign_aries_tmpl" id="sign_aries" class="sign sign-fire"> <use x="0" y="0" xlink:href="#sign_aries_tmpl" id="sign_aries" class="sign sign-fire">
<xsl:attribute name="transform">rotate(-15,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-15,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_taurus_tmpl" id="sign_taurus" class="sign sign-earth"> <use x="0" y="0" xlink:href="#sign_taurus_tmpl" id="sign_taurus" class="sign sign-earth">
<xsl:attribute name="transform">rotate(-45,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-45,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_gemini_tmpl" id="sign_gemini" class="sign sign-air"> <use x="0" y="0" xlink:href="#sign_gemini_tmpl" id="sign_gemini" class="sign sign-air">
<xsl:attribute name="transform">rotate(-75,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-75,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_cancer_tmpl" id="sign_cancer" class="sign sign-water"> <use x="0" y="0" xlink:href="#sign_cancer_tmpl" id="sign_cancer" class="sign sign-water">
<xsl:attribute name="transform">rotate(-105,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-105,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_leo_tmpl" id="sign_leo" class="sign sign-fire"> <use x="0" y="0" xlink:href="#sign_leo_tmpl" id="sign_leo" class="sign sign-fire">
<xsl:attribute name="transform">rotate(-135,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-135,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_virgo_tmpl" id="sign_virgo" class="sign sign-earth"> <use x="0" y="0" xlink:href="#sign_virgo_tmpl" id="sign_virgo" class="sign sign-earth">
<xsl:attribute name="transform">rotate(-165,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-165,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_libra_tmpl" id="sign_libra" class="sign sign-air"> <use x="0" y="0" xlink:href="#sign_libra_tmpl" id="sign_libra" class="sign sign-air">
<xsl:attribute name="transform">rotate(-195,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-195,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_scorpio_tmpl" id="sign_scorpio" class="sign sign-water"> <use x="0" y="0" xlink:href="#sign_scorpio_tmpl" id="sign_scorpio" class="sign sign-water">
<xsl:attribute name="transform">rotate(-225,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-225,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_sagittarius_tmpl" id="sign_sagittarius" class="sign sign-fire"> <use x="0" y="0" xlink:href="#sign_sagittarius_tmpl" id="sign_sagittarius" class="sign sign-fire">
<xsl:attribute name="transform">rotate(-255,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-255,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_capricorn_tmpl" id="sign_capricorn" class="sign sign-earth"> <use x="0" y="0" xlink:href="#sign_capricorn_tmpl" id="sign_capricorn" class="sign sign-earth">
<xsl:attribute name="transform">rotate(-285,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-285,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_aquarius_tmpl" id="sign_aquarius" class="sign sign-air"> <use x="0" y="0" xlink:href="#sign_aquarius_tmpl" id="sign_aquarius" class="sign sign-air">
<xsl:attribute name="transform">rotate(-315,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-315,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
<use x="0" y="0" xlink:href="#sign_pisces_tmpl" id="sign_pisces" class="sign sign-water"> <use x="0" y="0" xlink:href="#sign_pisces_tmpl" id="sign_pisces" class="sign sign-water">
<xsl:attribute name="transform">rotate(-345,0,0) translate(<xsl:value-of select="$chart_size * 0.435"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute> <xsl:attribute name="transform">rotate(-345,0,0) translate(<xsl:value-of select="$sign_pos"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>) scale(<xsl:value-of select="$icon_scale" />)</xsl:attribute>
</use> </use>
</g> </g>