diff --git a/src/ag-chart-renderer.h b/src/ag-chart-renderer.h index ae9c108..300a220 100644 --- a/src/ag-chart-renderer.h +++ b/src/ag-chart-renderer.h @@ -41,6 +41,7 @@ struct _AgChartRenderer }; #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_TILE_MARGIN AG_CHART_RENDERER_CHECK_ICON_SIZE / 4 #define AG_CHART_RENDERER_TILE_MARGIN_BOTTOM AG_CHART_RENDERER_CHECK_ICON_SIZE / 8 diff --git a/src/ag-chart.c b/src/ag-chart.c index e5eff28..d0b1e87 100644 --- a/src/ag-chart.c +++ b/src/ag-chart.c @@ -245,28 +245,30 @@ ag_chart_finalize(GObject *gobject) } void -ag_chart_add_planets(AgChart *chart) +ag_chart_add_planets(AgChart *chart, + const GswePlanet *planets, + guint planet_count) { int i; AgChartPrivate *priv = ag_chart_get_instance_private(chart); - for (i = 0; i < used_planets_count; i++) { - gswe_moment_add_planet(GSWE_MOMENT(chart), used_planets[i], NULL); + for (i = 0; i < planet_count; i++) { + gswe_moment_add_planet(GSWE_MOMENT(chart), planets[i], NULL); priv->planet_list = g_list_prepend( priv->planet_list, - GINT_TO_POINTER(used_planets[i]) + GINT_TO_POINTER(planets[i]) ); } priv->planet_list = g_list_reverse(priv->planet_list); } -AgChart * -ag_chart_new_full(GsweTimestamp *timestamp, - gdouble longitude, - gdouble latitude, - gdouble altitude, - GsweHouseSystem house_system) +static AgChart * +ag_chart_new_generic(GsweTimestamp *timestamp, + gdouble longitude, + gdouble latitude, + gdouble altitude, + GsweHouseSystem house_system) { AgChart *chart; GsweCoordinates *coords = g_new0(GsweCoordinates, 1); @@ -283,7 +285,52 @@ ag_chart_new_full(GsweTimestamp *timestamp, 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; } @@ -1176,12 +1223,12 @@ AgChart *ag_chart_load_from_placidus_file(GFile *file, } 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; gchar *house_system_enum_name; - GTypeClass *house_system_class; - GEnumValue *enum_value; GsweHouseSystem house_system; 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_class = g_type_class_ref(GSWE_TYPE_HOUSE_SYSTEM); - - 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; - } - + house_system = ag_house_system_nick_to_id(house_system_enum_name); g_free(house_system_enum_name); - house_system = enum_value->value; - timestamp = gswe_timestamp_new_from_gregorian_full( save_data->year, save_data->month, save_data->day, save_data->hour, save_data->minute, save_data->second, 0, save_data->timezone ); - chart = ag_chart_new_full( - timestamp, - save_data->longitude, - save_data->latitude, - save_data->altitude, - house_system - ); + if (preview) { + chart = ag_chart_new_preview( + timestamp, + save_data->longitude, + save_data->latitude, + 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_country(chart, save_data->country); @@ -1417,6 +1456,8 @@ ag_chart_create_svg(AgChart *chart, gsize *length, gboolean rendering, AgDisplayTheme *theme, + guint image_size, + guint icon_size, GError **err) { xmlDocPtr doc = create_save_doc(chart), @@ -1754,13 +1795,26 @@ ag_chart_create_svg(AgChart *chart, return NULL; } - params = g_new0(gchar *, 5); + params = g_new0(gchar *, 11); params[0] = "rendering"; params[1] = (rendering) ? "'yes'" : "'no'"; params[2] = "additional-css"; css = ag_display_theme_to_css(theme); params[3] = g_strdup_printf("\"%s\"", 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 // 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); xmlFreeDoc(doc); g_free(params[3]); + g_free(params[5]); + g_free(params[7]); + g_free(params[9]); g_free(params); // Now, svg_doc contains the generated SVG file @@ -1811,7 +1868,14 @@ ag_chart_export_svg_to_file(AgChart *chart, gchar *svg; 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; } @@ -1828,16 +1892,15 @@ ag_chart_export_svg_to_file(AgChart *chart, ); } -void -ag_chart_export_jpg_to_file(AgChart *chart, - GFile *file, - AgDisplayTheme *theme, - GError **err) +GdkPixbuf * +ag_chart_get_pixbuf(AgChart *chart, + guint image_size, + guint icon_size, + AgDisplayTheme *theme, + GError **err) { - gchar *svg, - *jpg; - gsize svg_length, - jpg_length; + gchar *svg; + gsize svg_length; RsvgHandle *svg_handle; GdkPixbuf *pixbuf; @@ -1846,19 +1909,21 @@ ag_chart_export_jpg_to_file(AgChart *chart, &svg_length, TRUE, theme, + image_size, + icon_size, err )) == NULL) { - return; + return NULL; } if ((svg_handle = rsvg_handle_new_from_data( - (const guint8 *)svg, + (const guint8 *)svg, svg_length, err )) == NULL) { g_free(svg); - return; + return NULL; } g_free(svg); @@ -1870,6 +1935,25 @@ ag_chart_export_jpg_to_file(AgChart *chart, _("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; } @@ -1926,7 +2010,7 @@ ag_chart_get_db_save(AgChart *chart, gint db_id) { GsweCoordinates *coords; 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)); GEnumClass *house_system_class; GEnumValue *house_system_enum; diff --git a/src/ag-chart.h b/src/ag-chart.h index fc0397a..0bf8bb3 100644 --- a/src/ag-chart.h +++ b/src/ag-chart.h @@ -22,10 +22,14 @@ #include #include #include +#include #include "ag-db.h" #include "ag-display-theme.h" +#define AG_CHART_DEFAULT_RING_SIZE 600 +#define AG_CHART_DEFAULT_ICON_SIZE 30 + G_BEGIN_DECLS typedef enum { @@ -63,7 +67,10 @@ struct _AgChartClass { 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; @@ -73,13 +80,21 @@ AgChart *ag_chart_new_full(GsweTimestamp *timestamp, gdouble altitude, 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, GError **err); AgChart *ag_chart_load_from_placidus_file(GFile *file, 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, GFile *file, @@ -114,6 +129,8 @@ gchar *ag_chart_create_svg(AgChart *chart, gsize *length, gboolean rendering, AgDisplayTheme *theme, + guint image_size, + guint icon_size, GError **err); 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); +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()) GQuark ag_chart_error_quark(void); diff --git a/src/ag-db.c b/src/ag-db.c index c7c3c97..d51916c 100644 --- a/src/ag-db.c +++ b/src/ag-db.c @@ -659,6 +659,14 @@ ag_db_chart_save(AgDb *db, AgDbChartSave *save_data, GError **err) note = G_VALUE_INIT; 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_set_string(&name, save_data->name); @@ -828,12 +836,13 @@ ag_db_chart_save(AgDb *db, AgDbChartSave *save_data, GError **err) } AgDbChartSave * -ag_db_chart_save_new(void) +ag_db_chart_save_new(gboolean populated) { AgDbChartSave *save_data; save_data = g_new0(AgDbChartSave, 1); save_data->refcount = 1; + save_data->populated = populated; return save_data; } @@ -874,7 +883,7 @@ ag_db_chart_get_list(AgDb *db, GError **err) while (gda_data_model_iter_move_next(iter)) { 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); 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; } - save_data = ag_db_chart_save_new(); + save_data = ag_db_chart_save_new(TRUE); /* id */ value = gda_data_model_get_value_at( diff --git a/src/ag-db.h b/src/ag-db.h index d29a699..e5c7e03 100644 --- a/src/ag-db.h +++ b/src/ag-db.h @@ -50,6 +50,7 @@ struct _AgDbClass { typedef struct _AgDbChartSave { gint db_id; + gboolean populated; gchar *name; gchar *country; gchar *city; @@ -84,7 +85,7 @@ gboolean ag_db_chart_save(AgDb *db, AgDbChartSave *save_data, 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); diff --git a/src/ag-display-theme.c b/src/ag-display-theme.c index c0a08bd..e1f32e6 100644 --- a/src/ag-display-theme.c +++ b/src/ag-display-theme.c @@ -35,6 +35,8 @@ static gchar *builtin_theme_name[AG_DISPLAY_THEME_COUNT] = { NC_("Display theme name", "No comets"), }; +static AgDisplayTheme *preview_theme = NULL; + gchar * 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_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; +} diff --git a/src/ag-display-theme.h b/src/ag-display-theme.h index 2541530..f554219 100644 --- a/src/ag-display-theme.h +++ b/src/ag-display-theme.h @@ -49,4 +49,6 @@ GList *ag_display_theme_get_list(void); void ag_display_theme_free(AgDisplayTheme *display_theme); +AgDisplayTheme *ag_display_theme_get_preview_theme(void); + #endif /* __AG_DISPLAY_THEME_H__ */ diff --git a/src/ag-icon-view.c b/src/ag-icon-view.c index bde569a..b6494a9 100644 --- a/src/ag-icon-view.c +++ b/src/ag-icon-view.c @@ -1,7 +1,11 @@ +#include + #include "ag-enumtypes.h" #include "ag-icon-view.h" #include "ag-db.h" #include "ag-chart-renderer.h" +#include "ag-display-theme.h" +#include "ag-chart.h" typedef struct _AgIconViewPrivate { AgIconViewMode mode; @@ -19,6 +23,7 @@ enum { enum { AG_ICON_VIEW_COLUMN_SELECTED, AG_ICON_VIEW_COLUMN_ITEM, + AG_ICON_VIEW_COLUMN_PIXBUF, 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_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)); @@ -122,12 +130,18 @@ ag_icon_view_button_press_event_cb(GtkWidget *widget, GtkIconView *gtk_icon_view = GTK_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) { gboolean selected; 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) { 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; 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); } @@ -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 ag_icon_view_text_renderer_func(GtkCellLayout *layout, GtkCellRenderer *renderer, @@ -226,7 +233,8 @@ ag_icon_view_init(AgIconView *icon_view) priv->model = gtk_list_store_new( AG_ICON_VIEW_COLUMN_COLUMNS, G_TYPE_BOOLEAN, - AG_TYPE_DB_CHART_SAVE + AG_TYPE_DB_CHART_SAVE, + GDK_TYPE_PIXBUF ); gtk_icon_view_set_model( GTK_ICON_VIEW(icon_view), @@ -267,6 +275,12 @@ ag_icon_view_init(AgIconView *icon_view) GTK_CELL_RENDERER(priv->thumb_renderer), "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(icon_view), GTK_CELL_RENDERER(priv->thumb_renderer), @@ -274,6 +288,7 @@ ag_icon_view_init(AgIconView *icon_view) icon_view, NULL ); +*/ priv->text_renderer = gtk_cell_renderer_text_new(); gtk_cell_renderer_set_alignment( @@ -298,15 +313,49 @@ void ag_icon_view_add_chart(AgIconView *icon_view, AgDbChartSave *chart_save) { 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); + 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_set( priv->model, &iter, 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 ); } diff --git a/src/ag-window.c b/src/ag-window.c index e31d736..536dab0 100644 --- a/src/ag-window.c +++ b/src/ag-window.c @@ -93,6 +93,22 @@ struct cc_search { 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_TYPE_WITH_PRIVATE(AgWindow, ag_window, GTK_TYPE_APPLICATION_WINDOW); @@ -516,6 +532,7 @@ ag_window_redraw_chart(AgWindow *window) &length, FALSE, NULL, + 0, 0, &err ); @@ -719,7 +736,7 @@ ag_window_recalculate_chart(AgWindow *window, gboolean set_everything) 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; @@ -1950,6 +1967,7 @@ ag_window_list_item_activated_cb(AgIconView *icon_view, if ((priv->chart = ag_chart_new_from_db_save( priv->saved_data, + FALSE, &err )) == NULL) { ag_app_message_dialog( @@ -2787,26 +2805,84 @@ ag_window_change_tab(AgWindow *window, const gchar *tab_name) ); } -static void -ag_window_add_chart_to_list(AgDbChartSave *save_data, AgWindow *window) +static gboolean +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 ag_window_load_chart_list(AgWindow *window) { - AgDb *db = ag_db_get(); - GError *err = NULL; - GList *chart_list = ag_db_chart_get_list(db, &err); + LoadIdleData *idle_data; + AgDb *db = ag_db_get(); + 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 - * loading would be a better idea. See: - * http://blogs.gnome.org/ebassi/documentation/lazy-loading/ - */ - g_list_foreach(chart_list, (GFunc)ag_window_add_chart_to_list, window); + /* Lazy loading of charts with previews. Idea is from + * http://blogs.gnome.org/ebassi/documentation/lazy-loading/ */ + + idle_data = g_new(LoadIdleData, 1); + 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; } diff --git a/src/resources/ui/chart-default.xsl b/src/resources/ui/chart-default.xsl index 96d8459..eb4c947 100644 --- a/src/resources/ui/chart-default.xsl +++ b/src/resources/ui/chart-default.xsl @@ -15,13 +15,53 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -35,22 +75,25 @@ planet planet- rotate(, 0, 0) - - + + - - + + translate(, ) rotate(, , ) #_tmpl - - - rotate(180, , ) - - + + + + rotate(180, , ) + + + scale() + @@ -151,24 +194,24 @@ - + - + - + - - + + @@ -183,8 +226,8 @@ - - + + @@ -211,8 +254,8 @@ - - + + @@ -251,8 +294,8 @@ - - + + @@ -543,40 +586,40 @@ - rotate(-15,0,0) translate(,-) rotate(90,,) + rotate(-15,0,0) translate(,-) rotate(90,,) scale() - rotate(-45,0,0) translate(,-) rotate(90,,) + rotate(-45,0,0) translate(,-) rotate(90,,) scale() - rotate(-75,0,0) translate(,-) rotate(90,,) + rotate(-75,0,0) translate(,-) rotate(90,,) scale() - rotate(-105,0,0) translate(,-) rotate(90,,) + rotate(-105,0,0) translate(,-) rotate(90,,) scale() - rotate(-135,0,0) translate(,-) rotate(90,,) + rotate(-135,0,0) translate(,-) rotate(90,,) scale() - rotate(-165,0,0) translate(,-) rotate(90,,) + rotate(-165,0,0) translate(,-) rotate(90,,) scale() - rotate(-195,0,0) translate(,-) rotate(90,,) + rotate(-195,0,0) translate(,-) rotate(90,,) scale() - rotate(-225,0,0) translate(,-) rotate(90,,) + rotate(-225,0,0) translate(,-) rotate(90,,) scale() - rotate(-255,0,0) translate(,-) rotate(90,,) + rotate(-255,0,0) translate(,-) rotate(90,,) scale() - rotate(-285,0,0) translate(,-) rotate(90,,) + rotate(-285,0,0) translate(,-) rotate(90,,) scale() - rotate(-315,0,0) translate(,-) rotate(90,,) + rotate(-315,0,0) translate(,-) rotate(90,,) scale() - rotate(-345,0,0) translate(,-) rotate(90,,) + rotate(-345,0,0) translate(,-) rotate(90,,) scale()