Compare commits

..

No commits in common. "8efd11d4e59b67d8fcf8e0d69cbb3cc9d62795e5" and "0bec06b55d847a9faad66f5a3b8331a9eb6bde03" have entirely different histories.

3 changed files with 17 additions and 106 deletions

View File

@ -2,16 +2,12 @@ fastiv
======
'fastiv' is a fast image viewer, supporting BMP, PNG, GIF, JPEG, and optionally
RAW, SVG and X11 cursors, or whatever gdk-pixbuf loads.
It still has some road to go, but it's already become quite usable,
and it has received basic polishing.
RAW and SVG pictures, or whatever gdk-pixbuf loads. Currently, it's very basic.
Non-goals
---------
- fancy UI--the focus is on speed of use first, colour accuracy second
- editing--that's what _editors_ are for, be it GIMP or Rawtherapee;
nothing beyond the most basic of adjustments is desired
- editing--that's what _editors_ are for, be it GIMP or Rawtherapee
- memory efficiency, though preloading can cause some pressure
- portability to non-UNIXy systems

View File

@ -43,7 +43,6 @@ struct _FastivBrowser {
FastivIoThumbnailSize item_size; ///< Thumbnail size
int item_height; ///< Thumbnail height in pixels
int item_spacing; ///< Space between items in pixels
GArray *entries; ///< [Entry]
GArray *layouted_rows; ///< [Row]
@ -61,6 +60,10 @@ typedef struct row Row;
static const double g_permitted_width_multiplier = 2;
// Could be split out to also-idiomatic row-spacing/column-spacing properties.
// TODO(p): Make a property for this.
static const int g_item_spacing = 1;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct entry {
@ -103,7 +106,7 @@ static void
append_row(FastivBrowser *self, int *y, int x, GArray *items_array)
{
if (self->layouted_rows->len)
*y += self->item_spacing;
*y += g_item_spacing;
*y += self->item_border_y;
g_array_append_val(self->layouted_rows, ((Row) {
@ -140,8 +143,8 @@ relayout(FastivBrowser *self, int width)
2 * self->item_border_x;
if (!items->len) {
// Just insert it, whether or not there's any space.
} else if (x + self->item_spacing + width <= available_width) {
x += self->item_spacing;
} else if (x + g_item_spacing + width <= available_width) {
x += g_item_spacing;
} else {
append_row(self, &y,
padding.left + MAX(0, available_width - x) / 2, items);
@ -482,23 +485,6 @@ fastiv_browser_get_property(
}
}
static void
set_item_size(FastivBrowser *self, FastivIoThumbnailSize size)
{
if (size < FASTIV_IO_THUMBNAIL_SIZE_MIN ||
size > FASTIV_IO_THUMBNAIL_SIZE_MAX)
return;
if (size != self->item_size) {
self->item_size = size;
self->item_height = fastiv_io_thumbnail_sizes[self->item_size].size;
reload_thumbnails(self);
g_object_notify_by_pspec(
G_OBJECT(self), browser_properties[PROP_THUMBNAIL_SIZE]);
}
}
static void
fastiv_browser_set_property(
GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
@ -506,7 +492,11 @@ fastiv_browser_set_property(
FastivBrowser *self = FASTIV_BROWSER(object);
switch (property_id) {
case PROP_THUMBNAIL_SIZE:
set_item_size(self, g_value_get_enum(value));
if (g_value_get_enum(value) != (int) self->item_size) {
self->item_size = g_value_get_enum(value);
self->item_height = fastiv_io_thumbnail_sizes[self->item_size].size;
reload_thumbnails(self);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
@ -560,8 +550,7 @@ fastiv_browser_realize(GtkWidget *widget)
.visual = gtk_widget_get_visual(widget),
.event_mask = gtk_widget_get_events(widget) | GDK_KEY_PRESS_MASK |
GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK |
GDK_SCROLL_MASK,
GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK,
};
// We need this window to receive input events at all.
@ -663,51 +652,6 @@ fastiv_browser_motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
return TRUE;
}
static gboolean
fastiv_browser_scroll_event(GtkWidget *widget, GdkEventScroll *event)
{
FastivBrowser *self = FASTIV_BROWSER(widget);
if ((event->state & gtk_accelerator_get_default_mod_mask()) !=
GDK_CONTROL_MASK)
return FALSE;
switch (event->direction) {
case GDK_SCROLL_UP:
set_item_size(self, self->item_size + 1);
return TRUE;
case GDK_SCROLL_DOWN:
set_item_size(self, self->item_size - 1);
return TRUE;
default:
// For some reason, we can also get GDK_SCROLL_SMOOTH.
// Left/right are good to steal from GtkScrolledWindow for consistency.
return TRUE;
}
}
static gboolean
fastiv_browser_query_tooltip(GtkWidget *widget, gint x, gint y,
G_GNUC_UNUSED gboolean keyboard_tooltip, GtkTooltip *tooltip)
{
FastivBrowser *self = FASTIV_BROWSER(widget);
const Entry *entry = entry_at(self, x, y);
if (!entry)
return FALSE;
GFile *file = g_file_new_for_path(entry->filename);
GFileInfo *info = g_file_query_info(file,
G_FILE_ATTRIBUTE_STANDARD_NAME
"," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
G_FILE_QUERY_INFO_NONE, NULL, NULL);
g_object_unref(file);
if (!info)
return FALSE;
gtk_tooltip_set_text(tooltip, g_file_info_get_display_name(info));
g_object_unref(info);
return TRUE;
}
static void
fastiv_browser_style_updated(GtkWidget *widget)
{
@ -717,11 +661,6 @@ fastiv_browser_style_updated(GtkWidget *widget)
GtkStyleContext *style = gtk_widget_get_style_context(widget);
GtkBorder border = {}, margin = {};
int item_spacing = self->item_spacing;
gtk_widget_style_get(widget, "spacing", &self->item_spacing, NULL);
if (item_spacing != self->item_spacing)
gtk_widget_queue_resize(widget);
// Using a pseudo-class, because GTK+ regions are deprecated.
gtk_style_context_save(style);
gtk_style_context_add_class(style, "item");
@ -802,16 +741,8 @@ fastiv_browser_class_init(FastivBrowserClass *klass)
widget_class->size_allocate = fastiv_browser_size_allocate;
widget_class->button_press_event = fastiv_browser_button_press_event;
widget_class->motion_notify_event = fastiv_browser_motion_notify_event;
widget_class->scroll_event = fastiv_browser_scroll_event;
widget_class->query_tooltip = fastiv_browser_query_tooltip;
widget_class->style_updated = fastiv_browser_style_updated;
// Could be split to also-idiomatic row-spacing/column-spacing properties.
// The GParamSpec is sinked by this call.
gtk_widget_class_install_style_property(widget_class,
g_param_spec_int("spacing", "Spacing", "Space between items",
0, G_MAXINT, 1, G_PARAM_READWRITE));
// TODO(p): Later override "screen_changed", recreate Pango layouts there,
// if we get to have any, or otherwise reflect DPI changes.
gtk_widget_class_set_css_name(widget_class, "fastiv-browser");
@ -821,14 +752,14 @@ static void
fastiv_browser_init(FastivBrowser *self)
{
gtk_widget_set_can_focus(GTK_WIDGET(self), TRUE);
gtk_widget_set_has_tooltip(GTK_WIDGET(self), TRUE);
self->entries = g_array_new(FALSE, TRUE, sizeof(Entry));
g_array_set_clear_func(self->entries, (GDestroyNotify) entry_free);
self->layouted_rows = g_array_new(FALSE, TRUE, sizeof(Row));
g_array_set_clear_func(self->layouted_rows, (GDestroyNotify) row_free);
set_item_size(self, FASTIV_IO_THUMBNAIL_SIZE_NORMAL);
self->item_size = FASTIV_IO_THUMBNAIL_SIZE_NORMAL;
self->item_height = fastiv_io_thumbnail_sizes[self->item_size].size;
self->selected = -1;
self->glow = cairo_image_surface_create(CAIRO_FORMAT_A1, 0, 0);

View File

@ -67,19 +67,6 @@ fastiv_sidebar_class_init(FastivSidebarClass *klass)
NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_FILE);
}
static gboolean
on_rowlabel_query_tooltip(GtkWidget *widget,
G_GNUC_UNUSED gint x, G_GNUC_UNUSED gint y,
G_GNUC_UNUSED gboolean keyboard_tooltip, GtkTooltip *tooltip)
{
GtkLabel *label = GTK_LABEL(widget);
if (!pango_layout_is_ellipsized(gtk_label_get_layout(label)))
return FALSE;
gtk_tooltip_set_text(tooltip, gtk_label_get_text(label));
return TRUE;
}
static GtkWidget *
create_row(GFile *file, const char *icon_name)
{
@ -101,9 +88,6 @@ create_row(GFile *file, const char *icon_name)
GtkWidget *rowlabel = gtk_label_new(name);
gtk_label_set_ellipsize(GTK_LABEL(rowlabel), PANGO_ELLIPSIZE_END);
gtk_widget_set_has_tooltip(rowlabel, TRUE);
g_signal_connect(rowlabel, "query-tooltip",
G_CALLBACK(on_rowlabel_query_tooltip), NULL);
gtk_style_context_add_class(
gtk_widget_get_style_context(rowlabel), "sidebar-label");
gtk_container_add(GTK_CONTAINER(rowbox), rowlabel);