#include #include #include "astrognome.h" #include "ag-display-theme.h" static gchar *planet_rule = ".planet-%s { visibility: hidden; }\n"; static gchar *aspect_type_rule = ".aspect-%s { visibility: hidden; }\n"; static gchar *aspect_planet_rule = ".aspect-p-%s { visibility: hidden; }\n"; static gchar *antiscion_type_rule = ".antiscion-%s { visibility: hidden; }\n"; static gchar *antiscion_planet_rule = ".antiscion-p-%s { visibility: hidden; }\n"; static AgDisplayTheme **builtin_themes = NULL; static gchar *builtin_theme_name[AG_DISPLAY_THEME_COUNT] = { NC_("Display theme name", "Everything"), NC_("Display theme name", "Classic"), NC_("Display theme name", "No comets"), }; gchar * ag_display_theme_to_css(AgDisplayTheme *theme) { gint i; GList *l, *all_aspects, *all_antiscion_axes; gchar *ret; GString *css = NULL; // Null themes are possible, deal with it! if (theme == NULL) { return g_strdup(""); } css = g_string_sized_new(300); // Go through the used_planets array. If any of them is not listed // by @theme, add a rule to hide it, and the respective aspects // and antiscia for (i = 0; i < used_planets_count; i++) { gboolean in_list; in_list = (g_list_find(theme->planets, GINT_TO_POINTER(used_planets[i])) != NULL); if (theme->planets_include != in_list) { const gchar *planet_name; planet_name = ag_planet_id_to_nick(used_planets[i]); g_string_append_printf(css, planet_rule, planet_name); g_string_append_printf(css, aspect_planet_rule, planet_name); g_string_append_printf(css, antiscion_planet_rule, planet_name); } } // Go through gswe_all_aspects(). If any of them is not listed by // @theme, add a rule to hide it all_aspects = gswe_all_aspects(); for (l = all_aspects; l; l = g_list_next(l)) { const gchar *aspect_type; gboolean in_list; GsweAspect aspect; GsweAspectInfo *aspect_info = l->data; aspect = gswe_aspect_info_get_aspect(aspect_info); in_list = (g_list_find(theme->aspects, GINT_TO_POINTER(aspect)) != NULL); aspect_type = ag_aspect_id_to_nick(aspect); if (theme->aspects_include != in_list) { g_string_append_printf(css, aspect_type_rule, aspect_type); } } g_list_free(all_aspects); // Go through gswe_all_antiscion_axes(). If any of them is not // listed by @theme, add a rule to hide it all_antiscion_axes = gswe_all_antiscion_axes(); for (l = all_antiscion_axes; l; l = g_list_next(l)) { const gchar *antiscion_axis_type; gboolean in_list; GsweAntiscionAxis antiscion_axis; GsweAntiscionAxisInfo *antiscion_axis_info = l->data; antiscion_axis = gswe_antiscion_axis_info_get_axis(antiscion_axis_info); in_list = (g_list_find(theme->antiscia, GINT_TO_POINTER(antiscion_axis)) != NULL); antiscion_axis_type = ag_antiscion_axis_id_to_nick(antiscion_axis); if (theme->antiscia_include != in_list) { g_string_append_printf(css, antiscion_type_rule, antiscion_axis_type); } } g_list_free(all_antiscion_axes); ret = g_string_free(css, FALSE); g_debug("Generated CSS:\n%s\n", ret); return ret; } static AgDisplayTheme * ag_display_theme_get_builtin(gint id) { AgDisplayTheme *theme; // Builtin themes all have a negative ID g_return_val_if_fail(id < 0, NULL); // And must be greater then AG_DISPLAY_THEME_COUNT g_return_val_if_fail(id >= -AG_DISPLAY_THEME_COUNT, NULL); if (builtin_themes == NULL) { builtin_themes = g_new0(AgDisplayTheme *, AG_DISPLAY_THEME_COUNT); } // If the theme is already created, return it if (builtin_themes[-id - 1] != NULL) { return builtin_themes[-id - 1]; } builtin_themes[-id - 1] = theme = g_new0(AgDisplayTheme, 1); switch (id) { case AG_DISPLAY_THEME_ALL: theme->id = id; theme->name = gettext(builtin_theme_name[-id - 1]); theme->builtin = TRUE; theme->planets_include = FALSE; theme->planets = NULL; theme->aspects_include = FALSE; theme->aspects = NULL; theme->antiscia_include = FALSE; theme->antiscia = NULL; break; case AG_DISPLAY_THEME_CLASSIC: // TODO: If SWE-GLib would support it, we could programatically get // classic planets and aspects here, thus, if it is messed up, // we need to fix it only once. theme->id = id; theme->name = gettext(builtin_theme_name[-id - 1]); theme->builtin = TRUE; theme->planets_include = TRUE; theme->planets = NULL; theme->aspects_include = TRUE; theme->aspects = NULL; theme->antiscia_include = TRUE; theme->antiscia = NULL; theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_SUN) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MOON) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MERCURY) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_VENUS) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MARS) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_JUPITER) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_SATURN) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MOON_NODE) ); theme->aspects = g_list_prepend( theme->aspects, GINT_TO_POINTER(GSWE_ASPECT_CONJUCTION) ); theme->aspects = g_list_prepend( theme->aspects, GINT_TO_POINTER(GSWE_ASPECT_OPPOSITION) ); theme->aspects = g_list_prepend( theme->aspects, GINT_TO_POINTER(GSWE_ASPECT_TRINE) ); theme->aspects = g_list_prepend( theme->aspects, GINT_TO_POINTER(GSWE_ASPECT_SQUARE) ); theme->aspects = g_list_prepend( theme->aspects, GINT_TO_POINTER(GSWE_ASPECT_SEXTILE) ); break; case AG_DISPLAY_THEME_NO_COMETS: // TODO: If SWE-GLib would support it, we could programatically get // classic planets and aspects here, thus, if it is messed up, // we need to fix it only once. theme->id = id; theme->name = gettext(builtin_theme_name[-id - 1]); theme->builtin = TRUE; theme->planets_include = TRUE; theme->planets = NULL; theme->aspects_include = FALSE; theme->aspects = NULL; theme->antiscia_include = FALSE; theme->antiscia = NULL; theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_SUN) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MOON) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MERCURY) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_VENUS) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MARS) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_JUPITER) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_SATURN) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_URANUS) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_NEPTUNE) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_PLUTO) ); theme->planets = g_list_prepend( theme->planets, GINT_TO_POINTER(GSWE_PLANET_MOON_NODE) ); break; default: g_free(theme); g_warning("Trying to instantiate unknown builtin theme %d", id); return NULL; } return theme; } GList * ag_display_theme_get_list(void) { int i; GList *ret = NULL; for (i = 1; i <= AG_DISPLAY_THEME_COUNT; i++) { AgDisplayTheme *theme; theme = ag_display_theme_get_builtin(-i); ret = g_list_append(ret, theme); } return ret; } AgDisplayTheme * ag_display_theme_get_by_id(int id) { if (id < 0) { return ag_display_theme_get_builtin(id); } g_warning("Invalid theme ID. Falling back to display everything."); return ag_display_theme_get_builtin(AG_DISPLAY_THEME_ALL); } void ag_display_theme_free(AgDisplayTheme *display_theme) { if (!display_theme || display_theme->builtin) { return; } g_free(display_theme->name); g_list_free(display_theme->planets); g_list_free(display_theme->aspects); g_list_free(display_theme->antiscia); g_free(display_theme); }