Add optional browser filename labels
This commit is contained in:
parent
38c19edc8b
commit
1b50a834a5
119
fiv-browser.c
119
fiv-browser.c
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// fiv-browser.c: filesystem browsing widget
|
// fiv-browser.c: filesystem browsing widget
|
||||||
//
|
//
|
||||||
// Copyright (c) 2021 - 2022, Přemysl Eric Janouch <p@janouch.name>
|
// Copyright (c) 2021 - 2023, Přemysl Eric Janouch <p@janouch.name>
|
||||||
//
|
//
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
// purpose with or without fee is hereby granted.
|
// purpose with or without fee is hereby granted.
|
||||||
|
@ -45,9 +45,12 @@
|
||||||
// │ n │ ┊ glow border │ n ┊
|
// │ n │ ┊ glow border │ n ┊
|
||||||
// │ g ╰───────────────────╯ g ╰┄┄┄┄┄
|
// │ g ╰───────────────────╯ g ╰┄┄┄┄┄
|
||||||
// │ s p a c i n g
|
// │ s p a c i n g
|
||||||
|
// │ l a b e l
|
||||||
|
// │ s p a c i n g
|
||||||
// │ ╭┄┄┄┄┄┄┄┄┄┄┄┄╮ ╭┄┄┄┄┄┄┄┄┄┄┄┄
|
// │ ╭┄┄┄┄┄┄┄┄┄┄┄┄╮ ╭┄┄┄┄┄┄┄┄┄┄┄┄
|
||||||
//
|
//
|
||||||
// The glow is actually a glowing margin, the border is rendered in two parts.
|
// The glow is actually a glowing margin, the border is rendered in two parts.
|
||||||
|
// When labels are hidden, the surrounding spacing is collapsed.
|
||||||
//
|
//
|
||||||
|
|
||||||
typedef struct entry Entry;
|
typedef struct entry Entry;
|
||||||
|
@ -72,6 +75,8 @@ struct _FivBrowser {
|
||||||
int item_height; ///< Thumbnail height in pixels
|
int item_height; ///< Thumbnail height in pixels
|
||||||
int item_spacing; ///< Space between items in pixels
|
int item_spacing; ///< Space between items in pixels
|
||||||
|
|
||||||
|
gboolean show_labels; ///< Show labels underneath items
|
||||||
|
|
||||||
FivIoModel *model; ///< Filesystem model
|
FivIoModel *model; ///< Filesystem model
|
||||||
GArray *entries; ///< []Entry
|
GArray *entries; ///< []Entry
|
||||||
GArray *layouted_rows; ///< []Row
|
GArray *layouted_rows; ///< []Row
|
||||||
|
@ -101,10 +106,13 @@ struct _FivBrowser {
|
||||||
/// The "last modified" timestamp of source images for thumbnails.
|
/// The "last modified" timestamp of source images for thumbnails.
|
||||||
static cairo_user_data_key_t fiv_browser_key_mtime_msec;
|
static cairo_user_data_key_t fiv_browser_key_mtime_msec;
|
||||||
|
|
||||||
|
// TODO(p): Include FivIoModelEntry data by reference.
|
||||||
struct entry {
|
struct entry {
|
||||||
gchar *uri; ///< GIO URI
|
gchar *uri; ///< GIO URI
|
||||||
gchar *target_uri; ///< GIO URI for any target
|
gchar *target_uri; ///< GIO URI for any target
|
||||||
|
gchar *display_name; ///< Label for the file
|
||||||
gint64 mtime_msec; ///< Modification time in milliseconds
|
gint64 mtime_msec; ///< Modification time in milliseconds
|
||||||
|
|
||||||
cairo_surface_t *thumbnail; ///< Prescaled thumbnail
|
cairo_surface_t *thumbnail; ///< Prescaled thumbnail
|
||||||
GIcon *icon; ///< If no thumbnail, use this icon
|
GIcon *icon; ///< If no thumbnail, use this icon
|
||||||
};
|
};
|
||||||
|
@ -114,6 +122,7 @@ entry_free(Entry *self)
|
||||||
{
|
{
|
||||||
g_free(self->uri);
|
g_free(self->uri);
|
||||||
g_free(self->target_uri);
|
g_free(self->target_uri);
|
||||||
|
g_free(self->display_name);
|
||||||
g_clear_pointer(&self->thumbnail, cairo_surface_destroy);
|
g_clear_pointer(&self->thumbnail, cairo_surface_destroy);
|
||||||
g_clear_object(&self->icon);
|
g_clear_object(&self->icon);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +131,8 @@ entry_free(Entry *self)
|
||||||
|
|
||||||
struct item {
|
struct item {
|
||||||
const Entry *entry;
|
const Entry *entry;
|
||||||
int x_offset; ///< Offset within the row
|
PangoLayout *label; ///< Label
|
||||||
|
int x_offset; ///< X offset within the row
|
||||||
};
|
};
|
||||||
|
|
||||||
struct row {
|
struct row {
|
||||||
|
@ -135,11 +145,34 @@ struct row {
|
||||||
static void
|
static void
|
||||||
row_free(Row *self)
|
row_free(Row *self)
|
||||||
{
|
{
|
||||||
|
for (gsize i = 0; i < self->len; i++)
|
||||||
|
g_clear_object(&self->items[i].label);
|
||||||
g_free(self->items);
|
g_free(self->items);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
static double
|
||||||
|
row_subheight(const FivBrowser *self, const Row *row)
|
||||||
|
{
|
||||||
|
if (!self->show_labels)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If we didn't ellipsize labels, this should be made to account
|
||||||
|
// for vertical centering as well.
|
||||||
|
int tallest_label = 0;
|
||||||
|
for (gsize i = 0; i < row->len; i++) {
|
||||||
|
PangoRectangle ink = {}, logical = {};
|
||||||
|
pango_layout_get_extents(row->items[i].label, &ink, &logical);
|
||||||
|
|
||||||
|
int height = (logical.y + logical.height) / PANGO_SCALE;
|
||||||
|
if (tallest_label < height)
|
||||||
|
tallest_label = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self->item_spacing + tallest_label;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_row(FivBrowser *self, int *y, int x, GArray *items_array)
|
append_row(FivBrowser *self, int *y, int x, GArray *items_array)
|
||||||
{
|
{
|
||||||
|
@ -154,6 +187,7 @@ append_row(FivBrowser *self, int *y, int x, GArray *items_array)
|
||||||
// Not trying to pack them vertically, but this would be the place to do it.
|
// Not trying to pack them vertically, but this would be the place to do it.
|
||||||
*y += self->item_height;
|
*y += self->item_height;
|
||||||
*y += self->item_border_y;
|
*y += self->item_border_y;
|
||||||
|
*y += row_subheight(self, &row);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -166,6 +200,9 @@ relayout(FivBrowser *self, int width)
|
||||||
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
||||||
int available_width = width - padding.left - padding.right, max_width = 0;
|
int available_width = width - padding.left - padding.right, max_width = 0;
|
||||||
|
|
||||||
|
// TODO(p): Remember the first visible item and the vertical offset into it,
|
||||||
|
// then try to ensure its visibility at the end (useful for reloads).
|
||||||
|
|
||||||
g_array_set_size(self->layouted_rows, 0);
|
g_array_set_size(self->layouted_rows, 0);
|
||||||
// Whatever self->drag_begin_* used to point at might no longer be there,
|
// Whatever self->drag_begin_* used to point at might no longer be there,
|
||||||
// but thumbnail reloading would disrupt mouse clicks if we cleared them.
|
// but thumbnail reloading would disrupt mouse clicks if we cleared them.
|
||||||
|
@ -189,8 +226,26 @@ relayout(FivBrowser *self, int width)
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_append_val(items,
|
PangoLayout *label = NULL;
|
||||||
((Item) {.entry = entry, .x_offset = x + self->item_border_x}));
|
if (self->show_labels) {
|
||||||
|
label = gtk_widget_create_pango_layout(widget, entry->display_name);
|
||||||
|
pango_layout_set_width(
|
||||||
|
label, (width - 2 * self->glow_w) * PANGO_SCALE);
|
||||||
|
pango_layout_set_alignment(label, PANGO_ALIGN_CENTER);
|
||||||
|
pango_layout_set_wrap(label, PANGO_WRAP_WORD_CHAR);
|
||||||
|
pango_layout_set_ellipsize(label, PANGO_ELLIPSIZE_END);
|
||||||
|
|
||||||
|
PangoAttrList *attrs = pango_attr_list_new();
|
||||||
|
pango_attr_list_insert(attrs, pango_attr_insert_hyphens_new(FALSE));
|
||||||
|
pango_layout_set_attributes(label, attrs);
|
||||||
|
pango_attr_list_unref (attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_append_val(items, ((Item) {
|
||||||
|
.entry = entry,
|
||||||
|
.label = label,
|
||||||
|
.x_offset = x + self->item_border_x,
|
||||||
|
}));
|
||||||
|
|
||||||
x += width;
|
x += width;
|
||||||
if (max_width < width)
|
if (max_width < width)
|
||||||
|
@ -366,6 +421,16 @@ draw_row(FivBrowser *self, cairo_t *cr, const Row *row)
|
||||||
// the whole rectangle with the selection color.
|
// the whole rectangle with the selection color.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->show_labels) {
|
||||||
|
gtk_style_context_save(style);
|
||||||
|
gtk_style_context_add_class(style, "label");
|
||||||
|
gtk_render_layout(style, cr, -border.left,
|
||||||
|
border.top + extents.height + self->item_border_y +
|
||||||
|
self->item_spacing,
|
||||||
|
item->label);
|
||||||
|
gtk_style_context_restore(style);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_restore(cr);
|
cairo_restore(cr);
|
||||||
gtk_style_context_restore(style);
|
gtk_style_context_restore(style);
|
||||||
}
|
}
|
||||||
|
@ -747,6 +812,7 @@ G_DEFINE_TYPE_EXTENDED(FivBrowser, fiv_browser, GTK_TYPE_WIDGET, 0,
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_THUMBNAIL_SIZE = 1,
|
PROP_THUMBNAIL_SIZE = 1,
|
||||||
|
PROP_SHOW_LABELS,
|
||||||
N_PROPERTIES,
|
N_PROPERTIES,
|
||||||
|
|
||||||
// These are overriden, we do not register them.
|
// These are overriden, we do not register them.
|
||||||
|
@ -827,6 +893,9 @@ fiv_browser_get_property(
|
||||||
case PROP_THUMBNAIL_SIZE:
|
case PROP_THUMBNAIL_SIZE:
|
||||||
g_value_set_enum(value, self->item_size);
|
g_value_set_enum(value, self->item_size);
|
||||||
break;
|
break;
|
||||||
|
case PROP_SHOW_LABELS:
|
||||||
|
g_value_set_boolean(value, self->show_labels);
|
||||||
|
break;
|
||||||
case PROP_HADJUSTMENT:
|
case PROP_HADJUSTMENT:
|
||||||
g_value_set_object(value, self->hadjustment);
|
g_value_set_object(value, self->hadjustment);
|
||||||
break;
|
break;
|
||||||
|
@ -872,6 +941,13 @@ fiv_browser_set_property(
|
||||||
case PROP_THUMBNAIL_SIZE:
|
case PROP_THUMBNAIL_SIZE:
|
||||||
set_item_size(self, g_value_get_enum(value));
|
set_item_size(self, g_value_get_enum(value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_SHOW_LABELS:
|
||||||
|
if (self->show_labels != g_value_get_boolean(value)) {
|
||||||
|
self->show_labels = g_value_get_boolean(value);
|
||||||
|
gtk_widget_queue_resize(GTK_WIDGET(self));
|
||||||
|
g_object_notify_by_pspec(object, pspec);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PROP_HADJUSTMENT:
|
case PROP_HADJUSTMENT:
|
||||||
if (replace_adjustment(
|
if (replace_adjustment(
|
||||||
self, &self->hadjustment, g_value_get_object(value)))
|
self, &self->hadjustment, g_value_get_object(value)))
|
||||||
|
@ -1283,12 +1359,13 @@ scroll_to_row(FivBrowser *self, const Row *row)
|
||||||
|
|
||||||
double y1 = gtk_adjustment_get_value(self->vadjustment);
|
double y1 = gtk_adjustment_get_value(self->vadjustment);
|
||||||
double ph = gtk_adjustment_get_page_size(self->vadjustment);
|
double ph = gtk_adjustment_get_page_size(self->vadjustment);
|
||||||
|
double sh = self->item_border_y + row_subheight(self, row);
|
||||||
if (row->y_offset < y1) {
|
if (row->y_offset < y1) {
|
||||||
gtk_adjustment_set_value(
|
gtk_adjustment_set_value(
|
||||||
self->vadjustment, row->y_offset - self->item_border_y);
|
self->vadjustment, row->y_offset - self->item_border_y);
|
||||||
} else if (row->y_offset + self->item_height > y1 + ph) {
|
} else if (row->y_offset + self->item_height + sh > y1 + ph) {
|
||||||
gtk_adjustment_set_value(self->vadjustment,
|
gtk_adjustment_set_value(
|
||||||
row->y_offset - ph + self->item_height + self->item_border_y);
|
self->vadjustment, row->y_offset - ph + self->item_height + sh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,20 +1536,16 @@ fiv_browser_query_tooltip(GtkWidget *widget, gint x, gint y,
|
||||||
G_GNUC_UNUSED gboolean keyboard_tooltip, GtkTooltip *tooltip)
|
G_GNUC_UNUSED gboolean keyboard_tooltip, GtkTooltip *tooltip)
|
||||||
{
|
{
|
||||||
FivBrowser *self = FIV_BROWSER(widget);
|
FivBrowser *self = FIV_BROWSER(widget);
|
||||||
|
|
||||||
|
// TODO(p): Consider getting rid of tooltips altogether.
|
||||||
|
if (self->show_labels)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
const Entry *entry = entry_at(self, x, y);
|
const Entry *entry = entry_at(self, x, y);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
GFile *file = g_file_new_for_uri(entry->uri);
|
gtk_tooltip_set_text(tooltip, entry->display_name);
|
||||||
GFileInfo *info =
|
|
||||||
g_file_query_info(file, 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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1553,6 +1626,13 @@ fiv_browser_style_updated(GtkWidget *widget)
|
||||||
gtk_style_context_add_class(style, "item");
|
gtk_style_context_add_class(style, "item");
|
||||||
gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin);
|
gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin);
|
||||||
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
||||||
|
// XXX: Right now, specifying custom fonts within our CSS pseudo-regions
|
||||||
|
// has no effect, so it might be appropriate to also add .label/.symbolic
|
||||||
|
// classes here, remember the resulting GTK_STYLE_PROPERTY_FONT,
|
||||||
|
// and apply them in relayout() with pango_layout_set_font_description().
|
||||||
|
// There is virtually nothing to be gained from this flexibility, though.
|
||||||
|
// XXX: We should also invoke relayout() here, because different states
|
||||||
|
// might theoretically use different fonts.
|
||||||
gtk_style_context_restore(style);
|
gtk_style_context_restore(style);
|
||||||
|
|
||||||
self->glow_w = (margin.left + margin.right) / 2;
|
self->glow_w = (margin.left + margin.right) / 2;
|
||||||
|
@ -1634,6 +1714,9 @@ fiv_browser_class_init(FivBrowserClass *klass)
|
||||||
"thumbnail-size", "Thumbnail size", "The thumbnail height to use",
|
"thumbnail-size", "Thumbnail size", "The thumbnail height to use",
|
||||||
FIV_TYPE_THUMBNAIL_SIZE, FIV_THUMBNAIL_SIZE_NORMAL,
|
FIV_TYPE_THUMBNAIL_SIZE, FIV_THUMBNAIL_SIZE_NORMAL,
|
||||||
G_PARAM_READWRITE);
|
G_PARAM_READWRITE);
|
||||||
|
browser_properties[PROP_SHOW_LABELS] = g_param_spec_boolean(
|
||||||
|
"show-labels", "Show labels", "Whether to show filename labels",
|
||||||
|
FALSE, G_PARAM_READWRITE);
|
||||||
g_object_class_install_properties(
|
g_object_class_install_properties(
|
||||||
object_class, N_PROPERTIES, browser_properties);
|
object_class, N_PROPERTIES, browser_properties);
|
||||||
|
|
||||||
|
@ -1703,6 +1786,7 @@ fiv_browser_init(FivBrowser *self)
|
||||||
g_queue_init(&self->thumbnailers_queue);
|
g_queue_init(&self->thumbnailers_queue);
|
||||||
|
|
||||||
set_item_size(self, FIV_THUMBNAIL_SIZE_NORMAL);
|
set_item_size(self, FIV_THUMBNAIL_SIZE_NORMAL);
|
||||||
|
self->show_labels = FALSE;
|
||||||
self->glow_padded = cairo_pattern_create_rgba(0, 0, 0, 0);
|
self->glow_padded = cairo_pattern_create_rgba(0, 0, 0, 0);
|
||||||
self->glow = cairo_pattern_create_rgba(0, 0, 0, 0);
|
self->glow = cairo_pattern_create_rgba(0, 0, 0, 0);
|
||||||
|
|
||||||
|
@ -1741,6 +1825,7 @@ on_model_files_changed(FivIoModel *model, FivBrowser *self)
|
||||||
Entry e = {.thumbnail = NULL,
|
Entry e = {.thumbnail = NULL,
|
||||||
.uri = g_strdup(files[i].uri),
|
.uri = g_strdup(files[i].uri),
|
||||||
.target_uri = g_strdup(files[i].target_uri),
|
.target_uri = g_strdup(files[i].target_uri),
|
||||||
|
.display_name = g_strdup(files[i].display_name),
|
||||||
.mtime_msec = files[i].mtime_msec};
|
.mtime_msec = files[i].mtime_msec};
|
||||||
g_array_append_val(self->entries, e);
|
g_array_append_val(self->entries, e);
|
||||||
}
|
}
|
||||||
|
|
5
fiv-io.c
5
fiv-io.c
|
@ -3049,6 +3049,7 @@ model_entry_finalize(FivIoModelEntry *entry)
|
||||||
{
|
{
|
||||||
g_free(entry->uri);
|
g_free(entry->uri);
|
||||||
g_free(entry->target_uri);
|
g_free(entry->target_uri);
|
||||||
|
g_free(entry->display_name);
|
||||||
g_free(entry->collate_key);
|
g_free(entry->collate_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3171,6 +3172,7 @@ model_reload_to(FivIoModel *self, GFile *directory,
|
||||||
GFileEnumerator *enumerator = g_file_enumerate_children(directory,
|
GFileEnumerator *enumerator = g_file_enumerate_children(directory,
|
||||||
G_FILE_ATTRIBUTE_STANDARD_TYPE ","
|
G_FILE_ATTRIBUTE_STANDARD_TYPE ","
|
||||||
G_FILE_ATTRIBUTE_STANDARD_NAME ","
|
G_FILE_ATTRIBUTE_STANDARD_NAME ","
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
|
||||||
G_FILE_ATTRIBUTE_STANDARD_TARGET_URI ","
|
G_FILE_ATTRIBUTE_STANDARD_TARGET_URI ","
|
||||||
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
|
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
|
||||||
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
|
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
|
||||||
|
@ -3205,7 +3207,8 @@ model_reload_to(FivIoModel *self, GFile *directory,
|
||||||
|
|
||||||
FivIoModelEntry entry = {.uri = g_file_get_uri(child),
|
FivIoModelEntry entry = {.uri = g_file_get_uri(child),
|
||||||
.target_uri = g_strdup(g_file_info_get_attribute_string(
|
.target_uri = g_strdup(g_file_info_get_attribute_string(
|
||||||
info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI))};
|
info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI)),
|
||||||
|
.display_name = g_strdup(g_file_info_get_display_name(info))};
|
||||||
GDateTime *mtime = g_file_info_get_modification_date_time(info);
|
GDateTime *mtime = g_file_info_get_modification_date_time(info);
|
||||||
if (mtime) {
|
if (mtime) {
|
||||||
entry.mtime_msec = g_date_time_to_unix(mtime) * 1000 +
|
entry.mtime_msec = g_date_time_to_unix(mtime) * 1000 +
|
||||||
|
|
5
fiv-io.h
5
fiv-io.h
|
@ -135,9 +135,14 @@ GFile *fiv_io_model_get_previous_directory(FivIoModel *self);
|
||||||
/// Returns the next VFS directory in order, or NULL.
|
/// Returns the next VFS directory in order, or NULL.
|
||||||
GFile *fiv_io_model_get_next_directory(FivIoModel *self);
|
GFile *fiv_io_model_get_next_directory(FivIoModel *self);
|
||||||
|
|
||||||
|
// TODO(p): Turn this into a reference-counted object.
|
||||||
|
// - If using g_rc_box_*(), we should wrap the {_acquire,_release_full}()
|
||||||
|
// functions as fiv_io_model_entry_{ref,unref}().
|
||||||
|
// - Ideally, all the strings would follow the struct immediately.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gchar *uri; ///< GIO URI
|
gchar *uri; ///< GIO URI
|
||||||
gchar *target_uri; ///< GIO URI for any target
|
gchar *target_uri; ///< GIO URI for any target
|
||||||
|
gchar *display_name; ///< Label for the file
|
||||||
gchar *collate_key; ///< Collate key for the filename
|
gchar *collate_key; ///< Collate key for the filename
|
||||||
gint64 mtime_msec; ///< Modification time in milliseconds
|
gint64 mtime_msec; ///< Modification time in milliseconds
|
||||||
} FivIoModelEntry;
|
} FivIoModelEntry;
|
||||||
|
|
21
fiv.c
21
fiv.c
|
@ -132,6 +132,7 @@ static struct key_group help_keys_browser[] = {
|
||||||
{"F9", "Toggle navigation sidebar"},
|
{"F9", "Toggle navigation sidebar"},
|
||||||
{"F5 r <Control>r", "Reload"},
|
{"F5 r <Control>r", "Reload"},
|
||||||
{"h <Control>h", "Toggle hiding unsupported files"},
|
{"h <Control>h", "Toggle hiding unsupported files"},
|
||||||
|
{"t <Control>t", "Toggle showing filenames"},
|
||||||
{"<Control>plus", "Larger thumbnails"},
|
{"<Control>plus", "Larger thumbnails"},
|
||||||
{"<Control>minus", "Smaller thumbnails"},
|
{"<Control>minus", "Smaller thumbnails"},
|
||||||
{}
|
{}
|
||||||
|
@ -1114,6 +1115,14 @@ on_dir_next(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_toggle_labels(void)
|
||||||
|
{
|
||||||
|
gboolean old = FALSE;
|
||||||
|
g_object_get(g.browser, "show-labels", &old, NULL);
|
||||||
|
g_object_set(g.browser, "show-labels", !old, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_toolbar_zoom(G_GNUC_UNUSED GtkButton *button, gpointer user_data)
|
on_toolbar_zoom(G_GNUC_UNUSED GtkButton *button, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
@ -1421,6 +1430,9 @@ on_key_press_browser_paned(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
|
||||||
case GDK_KEY_r:
|
case GDK_KEY_r:
|
||||||
load_directory(NULL);
|
load_directory(NULL);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
case GDK_KEY_t:
|
||||||
|
on_toggle_labels();
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GDK_MOD1_MASK:
|
case GDK_MOD1_MASK:
|
||||||
|
@ -1465,6 +1477,9 @@ on_key_press_browser_paned(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
|
||||||
case GDK_KEY_r:
|
case GDK_KEY_r:
|
||||||
load_directory(NULL);
|
load_directory(NULL);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
case GDK_KEY_t:
|
||||||
|
on_toggle_labels();
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1935,6 +1950,12 @@ static const char stylesheet[] = "@define-color fiv-tile @content_view_bg; \
|
||||||
background-size: 40px 40px; \
|
background-size: 40px 40px; \
|
||||||
background-position: 0 0, 0 20px, 20px -20px, -20px 0px; \
|
background-position: 0 0, 0 20px, 20px -20px, -20px 0px; \
|
||||||
} \
|
} \
|
||||||
|
fiv-browser.item.label, fiv-browser.item.symbolic.label { \
|
||||||
|
color: @theme_fg_color; \
|
||||||
|
} \
|
||||||
|
fiv-browser.item.label:backdrop:not(:selected) { \
|
||||||
|
color: @theme_unfocused_fg_color; \
|
||||||
|
} \
|
||||||
fiv-browser.item:selected { \
|
fiv-browser.item:selected { \
|
||||||
color: @theme_selected_bg_color; \
|
color: @theme_selected_bg_color; \
|
||||||
border-color: @theme_selected_bg_color; \
|
border-color: @theme_selected_bg_color; \
|
||||||
|
|
Loading…
Reference in New Issue