##### an offical release when making enhancements and translation updates. #####
Thu Mar 3 01:16:23 2005 John Ellis <johne@verizon.net>
* pan-view.c: Add 'dots' image size option, fix up border size at edge
of grid, and make drag and drop work to/from the window.
Wed Mar 2 23:34:30 2005 John Ellis <johne@verizon.net>
* globals.c, gqview.h, rcfile.c: Add thumbnail_fast option variable.
* image-load.c, typedefs.h: Add shrunk flag to determine if an image
was scaled down using image_loader_set_requested_size.
* image.c: Make panning with mouse scroll more when holding shift key.
* preferences.c: Add option for 'Fast jpeg thumbnailing' and disabled
xvpics option in the gui - now a hidden option.
* thumb.c, thumb_standard.c: Add support for thumbnail_fast option..
+Thu Mar 3 01:16:23 2005 John Ellis <johne@verizon.net>
+
+ * pan-view.c: Add 'dots' image size option, fix up border size at edge
+ of grid, and make drag and drop work to/from the window.
+
+Wed Mar 2 23:34:30 2005 John Ellis <johne@verizon.net>
+
+ * globals.c, gqview.h, rcfile.c: Add thumbnail_fast option variable.
+ * image-load.c, typedefs.h: Add shrunk flag to determine if an image
+ was scaled down using image_loader_set_requested_size.
+ * image.c: Make panning with mouse scroll more when holding shift key.
+ * preferences.c: Add option for 'Fast jpeg thumbnailing' and disabled
+ xvpics option in the gui - now a hidden option.
+ * thumb.c, thumb_standard.c: Add support for thumbnail_fast option..
+
Tue Mar 1 21:39:42 2005 John Ellis <johne@verizon.net>
* image.[ch] (image_scroll_to_point): Add alignment for location of
> Fix slowness in image.c with huge grid size by changing use of pre-allocated tile array
to on-demand tile allocation (can this be implemented like source tiles?).
OR: use an array so that we do not need to walk a GList of pre-allocated tile containers
- > Fix search scrolling to try to center image and info popup.
+ w> Fix search scrolling to try to center image and info popup.
> Fix info popup location to opposing horizontal side when near edge of grid.
> Find something to do with middle mouse clicks.
- > Set drag and drop data to clicked image.
- > Should the copy/move/rename/delete operations be available here?
+ d> Set drag and drop data to clicked image.
+ d> Should the copy/move/rename/delete operations be available here?
> ^ and if so, should delete key actually work?
> searching for same item more than once should step through all matches
> search should highlight all matching images
> should non-thumbnail images have a drop shadow?
> time line view:
- > searching by date should scroll to proper alignment with year/month/day boundaries.
+ d> searching by date should scroll to proper alignment with year/month/day boundaries.
> grid view:
> allow sorting by name, date, size, dimensions, etc.
> the info dialog is not set as a transient of the calling window, this causes it to be behind
a full screen window when 'stay above other windows' is enabled.
+ > use doubles instead of floats wherever possible
+
-------------
> update translations: ( ) ( ) ( )
> document recent additions/changes:
- (none currently)
+ > Added 'Fast jpeg thumbnailing'.
+ > xvpics is now hidden option.
+ > Holding down shift will now scroll more when panning with mouse.
Minor (non blockers):
gint enable_thumb_caching = TRUE;
gint enable_thumb_dirs = FALSE;
gint use_xvpics_thumbnails = TRUE;
+gint thumbnail_fast = TRUE;
gint thumbnail_spec_standard = TRUE;
gint enable_metadata_dirs = FALSE;
gint show_dot_files = FALSE;
extern gint thumb_max_height;
extern gint enable_thumb_caching;
extern gint enable_thumb_dirs;
+extern gint thumbnail_fast;
extern gint use_xvpics_thumbnails;
extern gint thumbnail_spec_standard;
extern gint enable_metadata_dirs;
}
gdk_pixbuf_loader_set_size(loader, nw, nh);
+ il->shrunk = TRUE;
}
}
g_signal_connect(G_OBJECT(il->loader), "size_prepared",
G_CALLBACK(image_loader_size_cb), il);
+ il->shrunk = FALSE;
+
return image_loader_begin(il);
}
il->requested_width = 0;
il->requested_height = 0;
+ il->shrunk = FALSE;
return il;
}
#include <math.h>
+/* size to use when breaking up image pane for rendering */
#define IMAGE_TILE_SIZE 512
+
+/* default min and max zoom */
#define IMAGE_ZOOM_MIN -32.0
#define IMAGE_ZOOM_MAX 32.0
/* distance to drag mouse to disable image flip */
#define IMAGE_DRAG_SCROLL_THRESHHOLD 4
+/* increase pan rate when holding down shift */
+#define IMAGE_PAN_SHIFT_MULTIPLIER 6
+
/* alpha channel checkerboard background (same as gimp) */
#define IMAGE_ALPHA_CHECK1 0x00999999
#define IMAGE_ALPHA_CHECK2 0x00666666
static gint image_mouse_motion_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
{
ImageWindow *imd = data;
+ gint accel;
if (imd->scroller_id != -1)
{
widget_set_cursor (imd->image, GDK_FLEUR);
}
+ if (bevent->state & GDK_SHIFT_MASK)
+ {
+ accel = IMAGE_PAN_SHIFT_MULTIPLIER;
+ }
+ else
+ {
+ accel = 1;
+ }
+
/* do the scroll */
- image_scroll_real(imd, imd->drag_last_x - bevent->x, imd->drag_last_y - bevent->y);
+ image_scroll_real(imd, (imd->drag_last_x - bevent->x) * accel,
+ (imd->drag_last_y - bevent->y) * accel);
imd->drag_last_x = bevent->x;
imd->drag_last_y = bevent->y;
widget_set_cursor(imd->image, -1);
}
- if (bevent->button == 1 && (bevent->state & GDK_SHIFT_MASK))
- {
- image_scroller_start(imd, bevent->x, bevent->y);
- }
- else if (bevent->button == 1 || bevent->button == 2)
+ if (imd->drag_moved < IMAGE_DRAG_SCROLL_THRESHHOLD)
{
- if (imd->drag_moved < IMAGE_DRAG_SCROLL_THRESHHOLD) image_button_do(imd, bevent);
+ if (bevent->button == 1 && (bevent->state & GDK_SHIFT_MASK))
+ {
+ image_scroller_start(imd, bevent->x, bevent->y);
+ }
+ else if (bevent->button == 1 || bevent->button == 2)
+ {
+ image_button_do(imd, bevent);
+ }
}
imd->in_drag = FALSE;
#define PAN_TILE_SIZE 512
+#define PAN_THUMB_SIZE_DOTS 4
#define PAN_THUMB_SIZE_NONE 24
#define PAN_THUMB_SIZE_SMALL 64
#define PAN_THUMB_SIZE_NORMAL 128
#define PAN_THUMB_SIZE_LARGE 256
#define PAN_THUMB_SIZE pw->thumb_size
+#define PAN_THUMB_GAP_DOTS 2
#define PAN_THUMB_GAP_SMALL 14
#define PAN_THUMB_GAP_NORMAL 30
#define PAN_THUMB_GAP_LARGE 40
} LayoutType;
typedef enum {
- LAYOUT_SIZE_THUMB_NONE = 0,
+ LAYOUT_SIZE_THUMB_DOTS = 0,
+ LAYOUT_SIZE_THUMB_NONE,
LAYOUT_SIZE_THUMB_SMALL,
LAYOUT_SIZE_THUMB_NORMAL,
LAYOUT_SIZE_THUMB_LARGE,
pi->height = child->y + child->height + border - pi->y;
}
+static void pan_item_size_coordinates(PanItem *pi, gint border, gint *w, gint *h)
+{
+ if (!pi) return;
+
+ if (*w < pi->x + pi->width + border) *w = pi->x + pi->width + border;
+ if (*h < pi->y + pi->height + border) *h = pi->y + pi->height + border;
+}
+
static void pan_item_image_find_size(PanWindow *pw, PanItem *pi, gint w, gint h)
{
GList *work;
GList *list;
GList *work;
gint x, y;
- gint w, h;
gint grid_size;
gint next_y;
next_y = 0;
- w = PAN_THUMB_GAP * 2;
- h = PAN_THUMB_GAP * 2;
+ *width = PAN_FOLDER_BOX_BORDER * 2;
+ *height = PAN_FOLDER_BOX_BORDER * 2;
x = PAN_THUMB_GAP;
y = PAN_THUMB_GAP;
y += PAN_THUMB_SIZE + PAN_THUMB_GAP;
}
}
-
- if (w < pi->x + pi->width + PAN_THUMB_GAP) w = pi->x + pi->width + PAN_THUMB_GAP;
- if (h < pi->y + pi->height + PAN_THUMB_GAP) h = pi->y + pi->height + PAN_THUMB_GAP;
+ pan_item_size_coordinates(pi, PAN_THUMB_GAP, width, height);
}
- if (width) *width = w;
- if (height) *height = h;
-
g_list_free(list);
}
f = filelist_sort(f, SORT_NAME, TRUE);
d = filelist_sort(d, SORT_NAME, TRUE);
- *x = PAN_THUMB_GAP + ((*level) * (PAN_THUMB_GAP * 2));
+ *x = PAN_FOLDER_BOX_BORDER + ((*level) * MAX(PAN_FOLDER_BOX_BORDER, PAN_THUMB_GAP));
pi_box = pan_item_new_text(pw, *x, *y, path, TEXT_ATTR_NONE,
PAN_TEXT_COLOR, 255);
if (*y < pi_box->y + pi_box->height + PAN_FOLDER_BOX_BORDER)
*y = pi_box->y + pi_box->height + PAN_FOLDER_BOX_BORDER;
- if (*width < pi_box->x + pi_box->width + PAN_FOLDER_BOX_BORDER)
- *width = pi_box->x + pi_box->width + PAN_FOLDER_BOX_BORDER;
- if (*height < pi_box->y + pi_box->height + PAN_FOLDER_BOX_BORDER)
- *height = pi_box->y + pi_box->height + PAN_FOLDER_BOX_BORDER;
+ pan_item_size_coordinates(pi_box, PAN_FOLDER_BOX_BORDER, width, height);
}
static void pan_window_layout_compute_folders_linear(PanWindow *pw, const gchar *path, gint *width, gint *height)
GList *list;
GList *work;
gint x, y;
- gint w, h;
time_t tc;
gint total;
gint count;
list = pan_window_layout_list(path, SORT_NONE, TRUE);
list = filelist_sort(list, SORT_TIME, TRUE);
- w = PAN_FOLDER_BOX_BORDER * 2;
- h = PAN_FOLDER_BOX_BORDER * 2;
+ *width = PAN_FOLDER_BOX_BORDER * 2;
+ *height = PAN_FOLDER_BOX_BORDER * 2;
x = 0;
y = 0;
pan_item_size_by_item(pi_day, pi, PAN_FOLDER_BOX_BORDER);
pan_item_size_by_item(pi_month, pi_day, PAN_FOLDER_BOX_BORDER);
-#if 0
- if (pi_day)
- {
- if (pi->x + pi->width + PAN_FOLDER_BOX_BORDER > pi_day->x + pi_day->width)
- pi_day->width = pi->x + pi->width + PAN_FOLDER_BOX_BORDER - pi_day->x;
- if (pi->y + pi->height + PAN_FOLDER_BOX_BORDER > pi_day->y + pi_day->height)
- pi_day->height = pi->y + pi->height + PAN_FOLDER_BOX_BORDER - pi_day->y;
- }
-
- if (pi_month && pi_day)
- {
- if (pi_day->x + pi_day->width + PAN_FOLDER_BOX_BORDER > pi_month->x + pi_month->width)
- pi_month->width = pi_day->x + pi_day->width + PAN_FOLDER_BOX_BORDER - pi_month->x;
- if (pi_day->y + pi_day->height + PAN_FOLDER_BOX_BORDER > pi_month->y + pi_month->height)
- pi_month->height = pi_day->y + pi_day->height + PAN_FOLDER_BOX_BORDER - pi_month->y;
- }
-#endif
total--;
count++;
y = month_start;
}
- if (w < pi->x + pi->width + PAN_THUMB_GAP) w = pi->x + pi->width + PAN_THUMB_GAP;
- if (h < pi->y + pi->height + PAN_THUMB_GAP) h = pi->y + pi->height + PAN_THUMB_GAP;
+ pan_item_size_coordinates(pi_month, PAN_FOLDER_BOX_BORDER, width, height);
}
- w += PAN_FOLDER_BOX_BORDER;
- h += PAN_FOLDER_BOX_BORDER;
-
- if (width) *width = w;
- if (height) *height = h;
-
g_list_free(list);
}
switch (pw->size)
{
+ case LAYOUT_SIZE_THUMB_DOTS:
+ pw->thumb_size = PAN_THUMB_SIZE_DOTS;
+ pw->thumb_gap = PAN_THUMB_GAP_DOTS;
+ break;
case LAYOUT_SIZE_THUMB_NONE:
pw->thumb_size = PAN_THUMB_SIZE_NONE;
pw->thumb_gap = PAN_THUMB_GAP_SMALL;
static void pan_layout_queue(PanWindow *pw, PanItem *pi)
{
if (!pi || pi->queued || pi->pixbuf) return;
- if (pw->size == LAYOUT_SIZE_THUMB_NONE) return;
+ if (pw->size <= LAYOUT_SIZE_THUMB_NONE) return;
pi->queued = TRUE;
pw->queue = g_list_prepend(pw->queue, pi);
{
gint d;
- d = (pw->size == LAYOUT_SIZE_THUMB_NONE) ? 2 : 8;
+ d = (pw->size <= LAYOUT_SIZE_THUMB_NONE) ? 2 : 8;
pixbuf_draw_rect_fill(pixbuf,
rx - x, ry - y, rw, rh,
PAN_SHADOW_COLOR,
switch (pw->size)
{
+ case LAYOUT_SIZE_THUMB_DOTS:
case LAYOUT_SIZE_THUMB_NONE:
case LAYOUT_SIZE_THUMB_SMALL:
case LAYOUT_SIZE_THUMB_NORMAL:
gtk_widget_show(combo);
combo = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Dots"));
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("No Images"));
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Small Thumbnails"));
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Normal Thumbnails"));
gtk_container_add(GTK_CONTAINER(frame), hbox);
gtk_widget_show(hbox);
- pref_spacer(hbox, PREF_PAD_SPACE);
+ pref_spacer(hbox, 0);
pw->label_message = pref_label_new(hbox, "");
frame = gtk_frame_new(NULL);
*/
static void pan_window_get_dnd_data(GtkWidget *widget, GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data, guint info,
- guint time, gpointer data)
+ gint x, gint y,
+ GtkSelectionData *selection_data, guint info,
+ guint time, gpointer data)
{
PanWindow *pw = data;
ImageWindow *imd;
list = uri_list_from_text(selection_data->data, TRUE);
if (list && isdir((gchar *)list->data))
{
- printf("FIXME: change to this folder: %s\n", (gchar *)list->data);
+ gchar *path = list->data;
+
+ g_free(pw->path);
+ pw->path = g_strdup(path);
+
+ pan_window_layout_update_idle(pw);
}
path_list_free(list);
}
static void pan_window_set_dnd_data(GtkWidget *widget, GdkDragContext *context,
- GtkSelectionData *selection_data, guint info,
- guint time, gpointer data)
+ GtkSelectionData *selection_data, guint info,
+ guint time, gpointer data)
{
- printf("FIXME: set dnd data\n");
+ PanWindow *pw = data;
+ const gchar *path;
+
+ path = pan_menu_click_path(pw);
+ if (path)
+ {
+ gchar *text = NULL;
+ gint len;
+ gint plain_text;
+ GList *list;
+
+ switch (info)
+ {
+ case TARGET_URI_LIST:
+ plain_text = FALSE;
+ break;
+ case TARGET_TEXT_PLAIN:
+ default:
+ plain_text = TRUE;
+ break;
+ }
+ list = g_list_append(NULL, (gchar *)path);
+ text = uri_text_from_list(list, &len, plain_text);
+ g_list_free(list);
+ if (text)
+ {
+ gtk_selection_data_set (selection_data, selection_data->target,
+ 8, text, len);
+ g_free(text);
+ }
+ }
+ else
+ {
+ gtk_selection_data_set (selection_data, selection_data->target,
+ 8, NULL, 0);
+ }
}
static void pan_window_dnd_init(PanWindow *pw)
static gint thumb_max_height_c;
static gint enable_thumb_caching_c;
static gint enable_thumb_dirs_c;
+static gint thumbnail_fast_c;
+#if 0
static gint use_xvpics_thumbnails_c;
+#endif
static gint thumbnail_spec_standard_c;
static gint enable_metadata_dirs_c;
static gint show_dot_files_c;
thumb_max_height = thumb_max_height_c;
enable_thumb_caching = enable_thumb_caching_c;
enable_thumb_dirs = enable_thumb_dirs_c;
+ thumbnail_fast = thumbnail_fast_c;
+#if 0
use_xvpics_thumbnails = use_xvpics_thumbnails_c;
+#endif
thumbnail_spec_standard = thumbnail_spec_standard_c;
enable_metadata_dirs = enable_metadata_dirs_c;
show_dot_files = show_dot_files_c;
subgroup = pref_box_new(subgroup, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
pref_checkbox_link_sensitivity_swap(button, subgroup);
- button = pref_checkbox_new_int(subgroup, _("Cache thumbnails into .thumbnails"),
- enable_thumb_dirs, &enable_thumb_dirs_c);
+ pref_checkbox_new_int(subgroup, _("Cache thumbnails into .thumbnails"),
+ enable_thumb_dirs, &enable_thumb_dirs_c);
+
+#if 0
+ pref_checkbox_new_int(subgroup, _("Use xvpics thumbnails when found (read only)"),
+ use_xvpics_thumbnails, &use_xvpics_thumbnails_c);
+#endif
- button = pref_checkbox_new_int(subgroup, _("Use xvpics thumbnails when found (read only)"),
- use_xvpics_thumbnails, &use_xvpics_thumbnails_c);
+ pref_checkbox_new_int(group, _("Faster jpeg thumbnailing (may reduce quality)"),
+ thumbnail_fast, &thumbnail_fast_c);
group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
write_int_option(f, "thumbnail_height", thumb_max_height);
write_bool_option(f, "cache_thumbnails", enable_thumb_caching);
write_bool_option(f, "cache_thumbnails_into_dirs", enable_thumb_dirs);
+ write_bool_option(f, "thumbnail_fast", thumbnail_fast);
write_bool_option(f, "use_xvpics_thumbnails", use_xvpics_thumbnails);
write_bool_option(f, "thumbnail_spec_standard", thumbnail_spec_standard);
fprintf(f,"\n");
"cache_thumbnails", value, enable_thumb_caching);
enable_thumb_dirs = read_bool_option(f, option,
"cache_thumbnails_into_dirs", value, enable_thumb_dirs);
+ thumbnail_fast = read_bool_option(f, option,
+ "thumbnail_fast", value, thumbnail_fast);
use_xvpics_thumbnails = read_bool_option(f, option,
"use_xvpics_thumbnails", value, use_xvpics_thumbnails);
thumbnail_spec_standard = read_bool_option(f, option,
{
gint w, h;
- if (((float)tl->max_w / pw) < ((float)tl->max_h / ph))
+ if (((double)tl->max_w / pw) < ((double)tl->max_h / ph))
{
w = tl->max_w;
- h = (float)w / pw * ph;
+ h = (double)w / pw * ph;
if (h < 1) h = 1;
}
else
{
h = tl->max_h;
- w = (float)h / ph * pw;
+ w = (double)h / ph * pw;
if (w < 1) w = 1;
}
{
tl->pixbuf = pixbuf;
gdk_pixbuf_ref(tl->pixbuf);
- save = FALSE;
+ save = il->shrunk;
}
/* save it ? */
image_loader_free(tl->il);
tl->il = image_loader_new(path);
-#if 0
- /* this will speed up jpegs by up to 3x in some cases */
- image_loader_set_requested_size(tl->max_w, tl->max_h);
-#endif
+ if (thumbnail_fast)
+ {
+ /* this will speed up jpegs by up to 3x in some cases */
+ image_loader_set_requested_size(tl->il, tl->max_w, tl->max_h);
+ }
image_loader_set_error_func(tl->il, thumb_loader_error_cb, tl);
if (tl->func_progress) image_loader_set_percent_func(tl->il, thumb_loader_percent_cb, tl);
return (*new_w != old_w || *new_h != old_h);
}
-static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf)
+static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf, gint shrunk)
{
GdkPixbuf *pixbuf_thumb = NULL;
GdkPixbuf *result;
sh = gdk_pixbuf_get_height(pixbuf);
if (tl->cache_enable && !tl->cache_hit &&
- (sw >= THUMB_SIZE_NORMAL || sh >= THUMB_SIZE_NORMAL))
+ (sw >= THUMB_SIZE_NORMAL || sh >= THUMB_SIZE_NORMAL || shrunk))
{
gint cache_w, cache_h;
gint thumb_w, thumb_h;
tl->cache_hit = (tl->thumb_path != NULL);
- tl->pixbuf = thumb_loader_std_finish(tl, pixbuf);
+ tl->pixbuf = thumb_loader_std_finish(tl, pixbuf, il->shrunk);
if (tl->func_done) tl->func_done(tl, tl->data);
}
{
tl->il = image_loader_new(path);
-#if 0
- /* this will speed up jpegs by up to 3x in some cases */
- if (tl->requested_width <= THUMB_SIZE_NORMAL &&
- tl->requested_height <= THUMB_SIZE_NORMAL)
+ if (thumbnail_fast)
{
- image_loader_set_requested_size(tl->il, THUMB_SIZE_NORMAL, THUMB_SIZE_NORMAL);
- }
- else
- {
- image_loader_set_requested_size(tl->il, THUMB_SIZE_LARGE, THUMB_SIZE_LARGE);
+ /* this will speed up jpegs by up to 3x in some cases */
+ if (tl->requested_width <= THUMB_SIZE_NORMAL &&
+ tl->requested_height <= THUMB_SIZE_NORMAL)
+ {
+ image_loader_set_requested_size(tl->il, THUMB_SIZE_NORMAL, THUMB_SIZE_NORMAL);
+ }
+ else
+ {
+ image_loader_set_requested_size(tl->il, THUMB_SIZE_LARGE, THUMB_SIZE_LARGE);
+ }
}
-#endif
image_loader_set_error_func(tl->il, thumb_loader_std_error_cb, tl);
if (tl->func_progress)
gint requested_width;
gint requested_height;
+ gint shrunk;
gint done;
gint idle_id;