📄 image.c
字号:
}#endif/* this read ahead is located here merely for the callbacks, above */static gint image_read_ahead_check(ImageWindow *imd){ if (!imd->read_ahead_path) return FALSE; if (imd->il) return FALSE; if (!imd->image_path || strcmp(imd->read_ahead_path, imd->image_path) != 0) { image_read_ahead_cancel(imd); return FALSE; } if (imd->read_ahead_il) { imd->il = imd->read_ahead_il; imd->read_ahead_il = NULL; /* override the old signals */ image_loader_set_area_ready_func(imd->il, image_load_area_cb, imd); image_loader_set_error_func(imd->il, image_load_error_cb, imd); image_loader_set_buffer_size(imd->il, IMAGE_LOAD_BUFFER_COUNT);#ifdef IMAGE_THROTTLE_LARGER_IMAGES image_load_buffer_throttle(imd->il);#endif /* do this one directly (probably should add a set func) */ imd->il->func_done = image_load_done_cb; g_object_set(G_OBJECT(imd->pr), "loading", TRUE, NULL); if (!imd->delay_flip) { image_change_pixbuf(imd, image_loader_get_pixbuf(imd->il), image_zoom_get(imd)); } image_read_ahead_cancel(imd); return TRUE; } else if (imd->read_ahead_pixbuf) { image_change_pixbuf(imd, imd->read_ahead_pixbuf, image_zoom_get(imd)); g_object_unref(imd->read_ahead_pixbuf); imd->read_ahead_pixbuf = NULL; image_read_ahead_cancel(imd); image_post_process(imd, FALSE); return TRUE; } image_read_ahead_cancel(imd); return FALSE;}static gint image_load_begin(ImageWindow *imd, const gchar *path){ if (debug) printf ("image begin \n"); if (imd->il) return FALSE; imd->completed = FALSE; g_object_set(G_OBJECT(imd->pr), "complete", FALSE, NULL); if (image_post_buffer_get(imd)) { if (debug) printf("from post buffer: %s\n", imd->image_path); return TRUE; } if (image_read_ahead_check(imd)) { if (debug) printf("from read ahead buffer: %s\n", imd->image_path); return TRUE; } if (!imd->delay_flip && image_get_pixbuf(imd)) { PixbufRenderer *pr; pr = PIXBUF_RENDERER(imd->pr); if (pr->pixbuf) g_object_unref(pr->pixbuf); pr->pixbuf = NULL; } g_object_set(G_OBJECT(imd->pr), "loading", TRUE, NULL); imd->il = image_loader_new(path); image_loader_set_area_ready_func(imd->il, image_load_area_cb, imd); image_loader_set_error_func(imd->il, image_load_error_cb, imd); image_loader_set_buffer_size(imd->il, IMAGE_LOAD_BUFFER_COUNT); if (!image_loader_start(imd->il, image_load_done_cb, imd)) { if (debug) printf("image start error\n"); g_object_set(G_OBJECT(imd->pr), "loading", FALSE, NULL); image_loader_free(imd->il); imd->il = NULL; image_complete_util(imd, FALSE); return FALSE; }#ifdef IMAGE_THROTTLE_LARGER_IMAGES image_load_buffer_throttle(imd->il);#endif if (!imd->delay_flip && !image_get_pixbuf(imd)) image_load_pixbuf_ready(imd); return TRUE;}static void image_reset(ImageWindow *imd){ /* stops anything currently being done */ if (debug) printf("image reset\n"); g_object_set(G_OBJECT(imd->pr), "loading", FALSE, NULL); image_loader_free(imd->il); imd->il = NULL; imd->delay_alter_type = ALTER_NONE;}/* *------------------------------------------------------------------- * image changer *------------------------------------------------------------------- */static void image_change_complete(ImageWindow *imd, gdouble zoom, gint new){ image_reset(imd); if (imd->image_path && isfile(imd->image_path)) { PixbufRenderer *pr; pr = PIXBUF_RENDERER(imd->pr); pr->zoom = zoom; /* store the zoom, needed by the loader */ if (image_load_begin(imd, imd->image_path)) { imd->unknown = FALSE; } else { GdkPixbuf *pixbuf; pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); image_change_pixbuf(imd, pixbuf, zoom); g_object_unref(pixbuf); imd->unknown = TRUE; } imd->size = filesize(imd->image_path); imd->mtime = filetime(imd->image_path); } else { if (imd->image_path) { GdkPixbuf *pixbuf; pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); image_change_pixbuf(imd, pixbuf, zoom); g_object_unref(pixbuf); imd->mtime = filetime(imd->image_path); } else { image_change_pixbuf(imd, NULL, zoom); imd->mtime = 0; } imd->unknown = TRUE; imd->size = 0; } image_update_util(imd);}static void image_change_real(ImageWindow *imd, const gchar *path, CollectionData *cd, CollectInfo *info, gdouble zoom){ GdkPixbuf *pixbuf; GdkPixbuf *prev_pixbuf = NULL; gchar *prev_path = NULL; gint prev_clear = FALSE; imd->collection = cd; imd->collection_info = info; pixbuf = image_get_pixbuf(imd); if (enable_read_ahead && imd->image_path && pixbuf) { if (imd->il) { /* current image is not finished */ prev_clear = TRUE; } else { prev_path = g_strdup(imd->image_path); prev_pixbuf = pixbuf; g_object_ref(prev_pixbuf); } } g_free(imd->image_path); imd->image_path = g_strdup(path); imd->image_name = filename_from_path(imd->image_path); image_change_complete(imd, zoom, TRUE); if (prev_pixbuf) { image_post_buffer_set(imd, prev_path, prev_pixbuf); g_free(prev_path); g_object_unref(prev_pixbuf); } else if (prev_clear) { image_post_buffer_set(imd, NULL, NULL); } image_update_title(imd); image_new_util(imd);}/* *------------------------------------------------------------------- * focus stuff *------------------------------------------------------------------- */static void image_focus_paint(ImageWindow *imd, gint has_focus, GdkRectangle *area){ GtkWidget *widget; widget = imd->widget; if (!widget->window) return; if (has_focus) { gtk_paint_focus (widget->style, widget->window, GTK_STATE_ACTIVE, area, widget, "image_window", widget->allocation.x, widget->allocation.y, widget->allocation.width - 1, widget->allocation.height - 1); } else { gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, area, widget, "image_window", widget->allocation.x, widget->allocation.y, widget->allocation.width - 1, widget->allocation.height - 1); }}static gint image_focus_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data){ ImageWindow *imd = data; image_focus_paint(imd, GTK_WIDGET_HAS_FOCUS(widget), &event->area); return TRUE;}static gint image_focus_in_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data){ ImageWindow *imd = data; GTK_WIDGET_SET_FLAGS(imd->widget, GTK_HAS_FOCUS); image_focus_paint(imd, TRUE, NULL); return TRUE;}static gint image_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data){ ImageWindow *imd = data; GTK_WIDGET_UNSET_FLAGS(imd->widget, GTK_HAS_FOCUS); image_focus_paint(imd, FALSE, NULL); return TRUE;}gint image_overlay_add(ImageWindow *imd, GdkPixbuf *pixbuf, gint x, gint y, gint relative, gint always){ return pixbuf_renderer_overlay_add((PixbufRenderer *)imd->pr, pixbuf, x, y, relative, always);}void image_overlay_set(ImageWindow *imd, gint id, GdkPixbuf *pixbuf, gint x, gint y){ pixbuf_renderer_overlay_set((PixbufRenderer *)imd->pr, id, pixbuf, x, y);}gint image_overlay_get(ImageWindow *imd, gint id, GdkPixbuf **pixbuf, gint *x, gint *y){ return pixbuf_renderer_overlay_get((PixbufRenderer *)imd->pr, id, pixbuf, x, y);}void image_overlay_remove(ImageWindow *imd, gint id){ pixbuf_renderer_overlay_remove((PixbufRenderer *)imd->pr, id);}static gint image_scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data){ ImageWindow *imd = data; if (imd->func_scroll && event && event->type == GDK_SCROLL) { imd->func_scroll(imd, event->direction, event->time, event->x, event->y, event->state, imd->data_scroll); return TRUE; } return FALSE;}/* *------------------------------------------------------------------- * public interface *------------------------------------------------------------------- */void image_attach_window(ImageWindow *imd, GtkWidget *window, const gchar *title, const gchar *title_right, gint show_zoom){ imd->top_window = window; g_free(imd->title); imd->title = g_strdup(title); g_free(imd->title_right); imd->title_right = g_strdup(title_right); imd->title_show_zoom = show_zoom; if (!fit_window) window = NULL; pixbuf_renderer_set_parent((PixbufRenderer *)imd->pr, (GtkWindow *)window); image_update_title(imd);}void image_set_update_func(ImageWindow *imd, void (*func)(ImageWindow *imd, gpointer data), gpointer data){ imd->func_update = func; imd->data_update = data;}void image_set_complete_func(ImageWindow *imd, void (*func)(ImageWindow *, gint preload, gpointer), gpointer data){ imd->func_complete = func; imd->data_complete = data;}void image_set_new_func(ImageWindow *imd, void (*func)(ImageWindow *, gpointer), gpointer data){ imd->func_new = func; imd->data_new = data;}void image_set_button_func(ImageWindow *imd, void (*func)(ImageWindow *, gint button, guint32 time, gdouble x, gdouble y, guint state, gpointer), gpointer data){ imd->func_button = func; imd->data_button = data;}void image_set_scroll_func(ImageWindow *imd, void (*func)(ImageWindow *, GdkScrollDirection direction, guint32 time, gdouble x, gdouble y, guint state, gpointer), gpointer data){ imd->func_scroll = func; imd->data_scroll = data;}void image_set_scroll_notify_func(ImageWindow *imd, void (*func)(ImageWindow *imd, gint x, gint y, gint width, gint height, gpointer data), gpointer data){ imd->func_scroll_notify = func; imd->data_scroll_notify = data;}/* path, name */const gchar *image_get_path(ImageWindow *imd){ return imd->image_path;}const gchar *image_get_name(ImageWindow *imd){ return imd->image_name;}/* merely changes path string, does not change the image! */void image_set_path(ImageWindow *imd, const gchar *newpath){ g_free(imd->image_path); imd->image_path = g_strdup(newpath); imd->image_name = filename_from_path(imd->image_path); image_update_title(imd); image_new_util(imd);}/* load a new image */void image_change_path(ImageWindow *imd, const gchar *path, gdouble zoom){ if (imd->image_path == path || (path && imd->image_path && !strcmp(path, imd->image_path)) ) return; image_change_real(imd, path, NULL, NULL, zoom);}GdkPixbuf *image_get_pixbuf(ImageWindow *imd){ return pixbuf_renderer_get_pixbuf((PixbufRenderer *)imd->pr);}void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom){ pixbuf_renderer_set_pixbuf((PixbufRenderer *)imd->pr, pixbuf, zoom); image_new_util(imd);}void image_change_from_collection(ImageWindow *imd, CollectionData *cd, CollectInfo *info, gdouble zoom){ if (!cd || !info || !g_list_find(cd->list, info)) return; image_change_real(imd, info->path, cd, info, zoom);}CollectionData *image_get_collection(ImageWindow *imd, CollectInfo **info){ if (collection_to_number(imd->collection) >= 0) { if (g_list_find(imd->collection->list, imd->collection_info) != NULL) { if (info) *info = imd->collection_info; } else { if (info) *info = NULL; } return imd->collection; } if (info) *info = NULL; return NULL;}static void image_loader_sync_data(ImageLoader *il, gpointer data){ /* change data for the callbacks directly */ il->data_area_ready = data; il->data_error = data; il->data_done = data; il->data_percent = data;}/* this is more like a move function * it moves most data from source to imd */void image_change_from_image(ImageWindow *imd, ImageWindow *source){ if (imd == source) return; imd->unknown = source->unknown; imd->collection = source->collection; imd->collection_info = source->collection_info;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -