Compare commits
2 Commits
3bf41993a3
...
e663f02754
Author | SHA1 | Date | |
---|---|---|---|
e663f02754 | |||
1a190001fc |
188
fiv-browser.c
188
fiv-browser.c
@ -45,7 +45,7 @@ typedef struct entry Entry;
|
|||||||
typedef struct item Item;
|
typedef struct item Item;
|
||||||
typedef struct row Row;
|
typedef struct row Row;
|
||||||
|
|
||||||
typedef struct _Thumbnailer {
|
typedef struct {
|
||||||
FivBrowser *self; ///< Parent browser
|
FivBrowser *self; ///< Parent browser
|
||||||
Entry *target; ///< Currently processed Entry pointer
|
Entry *target; ///< Currently processed Entry pointer
|
||||||
GSubprocess *minion; ///< A slave for the current queue head
|
GSubprocess *minion; ///< A slave for the current queue head
|
||||||
@ -54,6 +54,10 @@ typedef struct _Thumbnailer {
|
|||||||
|
|
||||||
struct _FivBrowser {
|
struct _FivBrowser {
|
||||||
GtkWidget parent_instance;
|
GtkWidget parent_instance;
|
||||||
|
GtkAdjustment *hadjustment; ///< GtkScrollable boilerplate
|
||||||
|
GtkAdjustment *vadjustment; ///< GtkScrollable boilerplate
|
||||||
|
GtkScrollablePolicy hscroll_policy; ///< GtkScrollable boilerplate
|
||||||
|
GtkScrollablePolicy vscroll_policy; ///< GtkScrollable boilerplate
|
||||||
|
|
||||||
FivThumbnailSize item_size; ///< Thumbnail size
|
FivThumbnailSize item_size; ///< Thumbnail size
|
||||||
int item_height; ///< Thumbnail height in pixels
|
int item_height; ///< Thumbnail height in pixels
|
||||||
@ -62,7 +66,7 @@ struct _FivBrowser {
|
|||||||
FivIoModel *model; ///< Filesystem model
|
FivIoModel *model; ///< Filesystem model
|
||||||
GArray *entries; ///< []Entry
|
GArray *entries; ///< []Entry
|
||||||
GArray *layouted_rows; ///< []Row
|
GArray *layouted_rows; ///< []Row
|
||||||
int selected;
|
const Entry *selected; ///< Selected entry or NULL
|
||||||
|
|
||||||
Thumbnailer *thumbnailers; ///< Parallelized thumbnailers
|
Thumbnailer *thumbnailers; ///< Parallelized thumbnailers
|
||||||
size_t thumbnailers_len; ///< Thumbnailers array size
|
size_t thumbnailers_len; ///< Thumbnailers array size
|
||||||
@ -170,7 +174,21 @@ relayout(FivBrowser *self, int width)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_array_free(items, TRUE);
|
g_array_free(items, TRUE);
|
||||||
return y + padding.bottom;
|
int total_height = y + padding.bottom;
|
||||||
|
if (self->hadjustment) {
|
||||||
|
// TODO(p): Set it to the width. Ideally, bump it to the minimum width.
|
||||||
|
}
|
||||||
|
if (self->vadjustment) {
|
||||||
|
gtk_adjustment_set_lower(self->vadjustment, 0);
|
||||||
|
gtk_adjustment_set_upper(self->vadjustment, total_height);
|
||||||
|
gtk_adjustment_set_page_size(
|
||||||
|
self->vadjustment, gtk_widget_get_allocated_height(widget));
|
||||||
|
gtk_adjustment_set_page_increment(
|
||||||
|
self->vadjustment, gtk_widget_get_allocated_height(widget));
|
||||||
|
gtk_adjustment_set_step_increment(self->vadjustment,
|
||||||
|
self->item_height + self->item_spacing + 2 * self->item_border_y);
|
||||||
|
}
|
||||||
|
return total_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -225,6 +243,9 @@ item_extents(FivBrowser *self, const Item *item, const Row *row)
|
|||||||
static const Entry *
|
static const Entry *
|
||||||
entry_at(FivBrowser *self, int x, int y)
|
entry_at(FivBrowser *self, int x, int y)
|
||||||
{
|
{
|
||||||
|
if (self->vadjustment)
|
||||||
|
y += round(gtk_adjustment_get_value(self->vadjustment));
|
||||||
|
|
||||||
for (guint i = 0; i < self->layouted_rows->len; i++) {
|
for (guint i = 0; i < self->layouted_rows->len; i++) {
|
||||||
const Row *row = &g_array_index(self->layouted_rows, Row, i);
|
const Row *row = &g_array_index(self->layouted_rows, Row, i);
|
||||||
for (Item *item = row->items; item->entry; item++) {
|
for (Item *item = row->items; item->entry; item++) {
|
||||||
@ -246,21 +267,25 @@ draw_row(FivBrowser *self, cairo_t *cr, const Row *row)
|
|||||||
gtk_style_context_save(style);
|
gtk_style_context_save(style);
|
||||||
gtk_style_context_add_class(style, "item");
|
gtk_style_context_add_class(style, "item");
|
||||||
|
|
||||||
GdkRGBA glow_color = {};
|
|
||||||
GtkStateFlags state = gtk_style_context_get_state (style);
|
|
||||||
gtk_style_context_get_color(style, state, &glow_color);
|
|
||||||
|
|
||||||
GtkBorder border;
|
GtkBorder border;
|
||||||
gtk_style_context_get_border(style, state, &border);
|
GtkStateFlags common_state = gtk_style_context_get_state(style);
|
||||||
|
gtk_style_context_get_border(style, common_state, &border);
|
||||||
for (Item *item = row->items; item->entry; item++) {
|
for (Item *item = row->items; item->entry; item++) {
|
||||||
cairo_save(cr);
|
cairo_save(cr);
|
||||||
GdkRectangle extents = item_extents(self, item, row);
|
GdkRectangle extents = item_extents(self, item, row);
|
||||||
cairo_translate(cr, extents.x - border.left, extents.y - border.top);
|
cairo_translate(cr, extents.x - border.left, extents.y - border.top);
|
||||||
|
|
||||||
|
GtkStateFlags state = common_state;
|
||||||
|
if (item->entry == self->selected)
|
||||||
|
state |= GTK_STATE_FLAG_SELECTED;
|
||||||
|
|
||||||
gtk_style_context_save(style);
|
gtk_style_context_save(style);
|
||||||
|
gtk_style_context_set_state(style, state);
|
||||||
if (item->entry->icon) {
|
if (item->entry->icon) {
|
||||||
gtk_style_context_add_class(style, "symbolic");
|
gtk_style_context_add_class(style, "symbolic");
|
||||||
} else {
|
} else {
|
||||||
|
GdkRGBA glow_color = {};
|
||||||
|
gtk_style_context_get_color(style, state, &glow_color);
|
||||||
gdk_cairo_set_source_rgba(cr, &glow_color);
|
gdk_cairo_set_source_rgba(cr, &glow_color);
|
||||||
draw_outer_border(self, cr,
|
draw_outer_border(self, cr,
|
||||||
border.left + extents.width + border.right,
|
border.left + extents.width + border.right,
|
||||||
@ -288,6 +313,9 @@ draw_row(FivBrowser *self, cairo_t *cr, const Row *row)
|
|||||||
cairo_set_source_surface(
|
cairo_set_source_surface(
|
||||||
cr, item->entry->thumbnail, border.left, border.top);
|
cr, item->entry->thumbnail, border.left, border.top);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
// Here, we could consider multiplying
|
||||||
|
// the whole rectangle with the selection color.
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_restore(cr);
|
cairo_restore(cr);
|
||||||
@ -748,14 +776,18 @@ show_context_menu(GtkWidget *widget, GFile *file)
|
|||||||
|
|
||||||
// --- Boilerplate -------------------------------------------------------------
|
// --- Boilerplate -------------------------------------------------------------
|
||||||
|
|
||||||
// TODO(p): For proper navigation, we need to implement GtkScrollable.
|
|
||||||
G_DEFINE_TYPE_EXTENDED(FivBrowser, fiv_browser, GTK_TYPE_WIDGET, 0,
|
G_DEFINE_TYPE_EXTENDED(FivBrowser, fiv_browser, GTK_TYPE_WIDGET, 0,
|
||||||
/* G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE,
|
G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, NULL))
|
||||||
fiv_browser_scrollable_init) */)
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_THUMBNAIL_SIZE = 1,
|
PROP_THUMBNAIL_SIZE = 1,
|
||||||
N_PROPERTIES
|
N_PROPERTIES,
|
||||||
|
|
||||||
|
// These are overriden, we do not register them.
|
||||||
|
PROP_HADJUSTMENT,
|
||||||
|
PROP_VADJUSTMENT,
|
||||||
|
PROP_HSCROLL_POLICY,
|
||||||
|
PROP_VSCROLL_POLICY,
|
||||||
};
|
};
|
||||||
|
|
||||||
static GParamSpec *browser_properties[N_PROPERTIES];
|
static GParamSpec *browser_properties[N_PROPERTIES];
|
||||||
@ -768,6 +800,35 @@ enum {
|
|||||||
// Globals are, sadly, the canonical way of storing signal numbers.
|
// Globals are, sadly, the canonical way of storing signal numbers.
|
||||||
static guint browser_signals[LAST_SIGNAL];
|
static guint browser_signals[LAST_SIGNAL];
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_adjustment_value_changed(
|
||||||
|
G_GNUC_UNUSED GtkAdjustment *adjustment, gpointer user_data)
|
||||||
|
{
|
||||||
|
FivBrowser *self = FIV_BROWSER(user_data);
|
||||||
|
gtk_widget_queue_draw(GTK_WIDGET(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
replace_adjustment(
|
||||||
|
FivBrowser *self, GtkAdjustment **adjustment, GtkAdjustment *replacement)
|
||||||
|
{
|
||||||
|
if (*adjustment == replacement)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (*adjustment) {
|
||||||
|
g_signal_handlers_disconnect_by_func(
|
||||||
|
*adjustment, on_adjustment_value_changed, self);
|
||||||
|
g_clear_object(adjustment);
|
||||||
|
}
|
||||||
|
if (replacement) {
|
||||||
|
*adjustment = g_object_ref(replacement);
|
||||||
|
g_signal_connect(*adjustment, "value-changed",
|
||||||
|
G_CALLBACK(on_adjustment_value_changed), self);
|
||||||
|
// TODO(p): We should set it up, as it is done in relayout().
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fiv_browser_finalize(GObject *gobject)
|
fiv_browser_finalize(GObject *gobject)
|
||||||
{
|
{
|
||||||
@ -783,6 +844,9 @@ fiv_browser_finalize(GObject *gobject)
|
|||||||
cairo_surface_destroy(self->glow);
|
cairo_surface_destroy(self->glow);
|
||||||
g_clear_object(&self->pointer);
|
g_clear_object(&self->pointer);
|
||||||
|
|
||||||
|
replace_adjustment(self, &self->hadjustment, NULL);
|
||||||
|
replace_adjustment(self, &self->vadjustment, NULL);
|
||||||
|
|
||||||
G_OBJECT_CLASS(fiv_browser_parent_class)->finalize(gobject);
|
G_OBJECT_CLASS(fiv_browser_parent_class)->finalize(gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,6 +859,18 @@ 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_HADJUSTMENT:
|
||||||
|
g_value_set_object(value, self->hadjustment);
|
||||||
|
break;
|
||||||
|
case PROP_VADJUSTMENT:
|
||||||
|
g_value_set_object(value, self->vadjustment);
|
||||||
|
break;
|
||||||
|
case PROP_HSCROLL_POLICY:
|
||||||
|
g_value_set_enum(value, self->hscroll_policy);
|
||||||
|
break;
|
||||||
|
case PROP_VSCROLL_POLICY:
|
||||||
|
g_value_set_enum(value, self->vscroll_policy);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
}
|
}
|
||||||
@ -825,6 +901,30 @@ 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_HADJUSTMENT:
|
||||||
|
if (replace_adjustment(
|
||||||
|
self, &self->hadjustment, g_value_get_object(value)))
|
||||||
|
g_object_notify_by_pspec(object, pspec);
|
||||||
|
break;
|
||||||
|
case PROP_VADJUSTMENT:
|
||||||
|
if (replace_adjustment(
|
||||||
|
self, &self->vadjustment, g_value_get_object(value)))
|
||||||
|
g_object_notify_by_pspec(object, pspec);
|
||||||
|
break;
|
||||||
|
case PROP_HSCROLL_POLICY:
|
||||||
|
if ((gint) self->hscroll_policy != g_value_get_enum(value)) {
|
||||||
|
self->hscroll_policy = g_value_get_enum(value);
|
||||||
|
gtk_widget_queue_resize(GTK_WIDGET(self));
|
||||||
|
g_object_notify_by_pspec(object, pspec);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROP_VSCROLL_POLICY:
|
||||||
|
if ((gint) self->vscroll_policy != g_value_get_enum(value)) {
|
||||||
|
self->vscroll_policy = g_value_get_enum(value);
|
||||||
|
gtk_widget_queue_resize(GTK_WIDGET(self));
|
||||||
|
g_object_notify_by_pspec(object, pspec);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
}
|
}
|
||||||
@ -899,6 +999,7 @@ fiv_browser_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
|
|||||||
GTK_WIDGET_CLASS(fiv_browser_parent_class)
|
GTK_WIDGET_CLASS(fiv_browser_parent_class)
|
||||||
->size_allocate(widget, allocation);
|
->size_allocate(widget, allocation);
|
||||||
|
|
||||||
|
// TODO(p): Update adjustments so that blank space is avoided.
|
||||||
relayout(FIV_BROWSER(widget), allocation->width);
|
relayout(FIV_BROWSER(widget), allocation->width);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,6 +1015,12 @@ fiv_browser_draw(GtkWidget *widget, cairo_t *cr)
|
|||||||
gtk_render_background(gtk_widget_get_style_context(widget), cr, 0, 0,
|
gtk_render_background(gtk_widget_get_style_context(widget), cr, 0, 0,
|
||||||
allocation.width, allocation.height);
|
allocation.width, allocation.height);
|
||||||
|
|
||||||
|
// TODO(p): self->hadjustment as well, and test it.
|
||||||
|
if (self->vadjustment) {
|
||||||
|
gdouble y = round(gtk_adjustment_get_value(self->vadjustment));
|
||||||
|
cairo_translate(cr, 0, -y);
|
||||||
|
}
|
||||||
|
|
||||||
GdkRectangle clip = {};
|
GdkRectangle clip = {};
|
||||||
gboolean have_clip = gdk_cairo_get_clip_rectangle(cr, &clip);
|
gboolean have_clip = gdk_cairo_get_clip_rectangle(cr, &clip);
|
||||||
|
|
||||||
@ -957,8 +1064,21 @@ fiv_browser_button_press_event(GtkWidget *widget, GdkEventButton *event)
|
|||||||
gtk_widget_grab_focus(widget);
|
gtk_widget_grab_focus(widget);
|
||||||
|
|
||||||
const Entry *entry = entry_at(self, event->x, event->y);
|
const Entry *entry = entry_at(self, event->x, event->y);
|
||||||
if (!entry && event->button == GDK_BUTTON_SECONDARY) {
|
if (!entry && state == 0) {
|
||||||
show_context_menu(widget, fiv_io_model_get_location(self->model));
|
switch (event->button) {
|
||||||
|
case GDK_BUTTON_PRIMARY:
|
||||||
|
break;
|
||||||
|
case GDK_BUTTON_SECONDARY:
|
||||||
|
show_context_menu(widget, fiv_io_model_get_location(self->model));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->selected) {
|
||||||
|
self->selected = NULL;
|
||||||
|
gtk_widget_queue_draw(widget);
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (!entry)
|
if (!entry)
|
||||||
@ -976,6 +1096,9 @@ fiv_browser_button_press_event(GtkWidget *widget, GdkEventButton *event)
|
|||||||
return open_entry(widget, entry, TRUE);
|
return open_entry(widget, entry, TRUE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case GDK_BUTTON_SECONDARY:
|
case GDK_BUTTON_SECONDARY:
|
||||||
|
self->selected = entry;
|
||||||
|
gtk_widget_queue_draw(widget);
|
||||||
|
|
||||||
// On X11, after closing the menu, the pointer otherwise remains,
|
// On X11, after closing the menu, the pointer otherwise remains,
|
||||||
// no matter what its new location is.
|
// no matter what its new location is.
|
||||||
gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
|
gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
|
||||||
@ -1027,6 +1150,18 @@ fiv_browser_scroll_event(GtkWidget *widget, GdkEventScroll *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fiv_browser_key_press_event(GtkWidget *widget, GdkEventKey *event)
|
||||||
|
{
|
||||||
|
FivBrowser *self = FIV_BROWSER(widget);
|
||||||
|
if (!(event->state & gtk_accelerator_get_default_mod_mask()) &&
|
||||||
|
event->keyval == GDK_KEY_Return && self->selected)
|
||||||
|
return open_entry(widget, self->selected, FALSE);
|
||||||
|
|
||||||
|
return GTK_WIDGET_CLASS(fiv_browser_parent_class)
|
||||||
|
->key_press_event(widget, event);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fiv_browser_query_tooltip(GtkWidget *widget, gint x, gint y,
|
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)
|
||||||
@ -1129,6 +1264,15 @@ fiv_browser_class_init(FivBrowserClass *klass)
|
|||||||
g_object_class_install_properties(
|
g_object_class_install_properties(
|
||||||
object_class, N_PROPERTIES, browser_properties);
|
object_class, N_PROPERTIES, browser_properties);
|
||||||
|
|
||||||
|
g_object_class_override_property(
|
||||||
|
object_class, PROP_HADJUSTMENT, "hadjustment");
|
||||||
|
g_object_class_override_property(
|
||||||
|
object_class, PROP_VADJUSTMENT, "vadjustment");
|
||||||
|
g_object_class_override_property(
|
||||||
|
object_class, PROP_HSCROLL_POLICY, "hscroll-policy");
|
||||||
|
g_object_class_override_property(
|
||||||
|
object_class, PROP_VSCROLL_POLICY, "vscroll-policy");
|
||||||
|
|
||||||
browser_signals[ITEM_ACTIVATED] = g_signal_new("item-activated",
|
browser_signals[ITEM_ACTIVATED] = g_signal_new("item-activated",
|
||||||
G_TYPE_FROM_CLASS(klass), 0, 0, NULL, NULL, NULL,
|
G_TYPE_FROM_CLASS(klass), 0, 0, NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 2, G_TYPE_FILE, GTK_TYPE_PLACES_OPEN_FLAGS);
|
G_TYPE_NONE, 2, G_TYPE_FILE, GTK_TYPE_PLACES_OPEN_FLAGS);
|
||||||
@ -1144,6 +1288,7 @@ fiv_browser_class_init(FivBrowserClass *klass)
|
|||||||
widget_class->button_press_event = fiv_browser_button_press_event;
|
widget_class->button_press_event = fiv_browser_button_press_event;
|
||||||
widget_class->motion_notify_event = fiv_browser_motion_notify_event;
|
widget_class->motion_notify_event = fiv_browser_motion_notify_event;
|
||||||
widget_class->scroll_event = fiv_browser_scroll_event;
|
widget_class->scroll_event = fiv_browser_scroll_event;
|
||||||
|
widget_class->key_press_event = fiv_browser_key_press_event;
|
||||||
widget_class->query_tooltip = fiv_browser_query_tooltip;
|
widget_class->query_tooltip = fiv_browser_query_tooltip;
|
||||||
widget_class->style_updated = fiv_browser_style_updated;
|
widget_class->style_updated = fiv_browser_style_updated;
|
||||||
|
|
||||||
@ -1168,7 +1313,6 @@ fiv_browser_init(FivBrowser *self)
|
|||||||
g_array_set_clear_func(self->entries, (GDestroyNotify) entry_free);
|
g_array_set_clear_func(self->entries, (GDestroyNotify) entry_free);
|
||||||
self->layouted_rows = g_array_new(FALSE, TRUE, sizeof(Row));
|
self->layouted_rows = g_array_new(FALSE, TRUE, sizeof(Row));
|
||||||
g_array_set_clear_func(self->layouted_rows, (GDestroyNotify) row_free);
|
g_array_set_clear_func(self->layouted_rows, (GDestroyNotify) row_free);
|
||||||
self->selected = -1;
|
|
||||||
|
|
||||||
self->thumbnailers_len = g_get_num_processors();
|
self->thumbnailers_len = g_get_num_processors();
|
||||||
self->thumbnailers =
|
self->thumbnailers =
|
||||||
@ -1190,6 +1334,13 @@ on_model_files_changed(FivIoModel *model, FivBrowser *self)
|
|||||||
{
|
{
|
||||||
g_return_if_fail(model == self->model);
|
g_return_if_fail(model == self->model);
|
||||||
|
|
||||||
|
int selected = -1;
|
||||||
|
gchar *selected_uri = NULL;
|
||||||
|
if (self->selected) {
|
||||||
|
selected_uri = g_strdup(self->selected->uri);
|
||||||
|
self->selected = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(p): Later implement arguments.
|
// TODO(p): Later implement arguments.
|
||||||
thumbnailers_abort(self);
|
thumbnailers_abort(self);
|
||||||
g_array_set_size(self->entries, 0);
|
g_array_set_size(self->entries, 0);
|
||||||
@ -1199,10 +1350,17 @@ on_model_files_changed(FivIoModel *model, FivBrowser *self)
|
|||||||
for (guint i = 0; i < files->len; i++) {
|
for (guint i = 0; i < files->len; i++) {
|
||||||
g_array_append_val(self->entries,
|
g_array_append_val(self->entries,
|
||||||
((Entry) {.thumbnail = NULL, .uri = files->pdata[i]}));
|
((Entry) {.thumbnail = NULL, .uri = files->pdata[i]}));
|
||||||
|
if (!g_strcmp0(selected_uri, files->pdata[i]))
|
||||||
|
selected = i;
|
||||||
files->pdata[i] = NULL;
|
files->pdata[i] = NULL;
|
||||||
}
|
}
|
||||||
g_ptr_array_free(files, TRUE);
|
g_ptr_array_free(files, TRUE);
|
||||||
|
|
||||||
|
// Beware that the pointer may shift with the storage.
|
||||||
|
g_free(selected_uri);
|
||||||
|
if (selected >= 0)
|
||||||
|
self->selected = &g_array_index(self->entries, Entry, selected);
|
||||||
|
|
||||||
reload_thumbnails(self);
|
reload_thumbnails(self);
|
||||||
thumbnailers_start(self);
|
thumbnailers_start(self);
|
||||||
}
|
}
|
||||||
|
36
fiv.c
36
fiv.c
@ -567,7 +567,7 @@ switch_to_browser(void)
|
|||||||
{
|
{
|
||||||
set_window_title(g.directory);
|
set_window_title(g.directory);
|
||||||
gtk_stack_set_visible_child(GTK_STACK(g.stack), g.browser_paned);
|
gtk_stack_set_visible_child(GTK_STACK(g.stack), g.browser_paned);
|
||||||
gtk_widget_grab_focus(g.browser_scroller);
|
gtk_widget_grab_focus(g.browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1567,6 +1567,8 @@ make_browser_sidebar(FivIoModel *model)
|
|||||||
// thus resolving the problem using overlaps.
|
// thus resolving the problem using overlaps.
|
||||||
// We're trying to be universal for light and dark themes both. It's hard.
|
// We're trying to be universal for light and dark themes both. It's hard.
|
||||||
static const char stylesheet[] = "@define-color fiv-tile @content_view_bg; \
|
static const char stylesheet[] = "@define-color fiv-tile @content_view_bg; \
|
||||||
|
@define-color fiv-semiselected \
|
||||||
|
mix(@theme_selected_bg_color, @content_view_bg, 0.5); \
|
||||||
fiv-view, fiv-browser { background: @content_view_bg; } \
|
fiv-view, fiv-browser { background: @content_view_bg; } \
|
||||||
placessidebar.fiv .toolbar { padding: 2px 6px; } \
|
placessidebar.fiv .toolbar { padding: 2px 6px; } \
|
||||||
placessidebar.fiv box > separator { margin: 4px 0; } \
|
placessidebar.fiv box > separator { margin: 4px 0; } \
|
||||||
@ -1579,6 +1581,7 @@ static const char stylesheet[] = "@define-color fiv-tile @content_view_bg; \
|
|||||||
} \
|
} \
|
||||||
fiv-browser { padding: 5px; } \
|
fiv-browser { padding: 5px; } \
|
||||||
fiv-browser.item { \
|
fiv-browser.item { \
|
||||||
|
/* For non-symbolic, color is applied to the glowing margin. */ \
|
||||||
color: mix(#000, @content_view_bg, 0.625); margin: 8px; \
|
color: mix(#000, @content_view_bg, 0.625); margin: 8px; \
|
||||||
border: 2px solid #fff; \
|
border: 2px solid #fff; \
|
||||||
} \
|
} \
|
||||||
@ -1591,14 +1594,36 @@ 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:backdrop { \
|
fiv-browser.item:selected { \
|
||||||
|
color: @theme_selected_bg_color; \
|
||||||
|
border-color: @theme_selected_bg_color; \
|
||||||
|
} \
|
||||||
|
fiv-browser.item:selected:not(:focus) { \
|
||||||
|
color: @fiv-semiselected; \
|
||||||
|
border-color: @fiv-semiselected; \
|
||||||
|
} \
|
||||||
|
fiv-browser.item:backdrop:not(:selected) { \
|
||||||
color: mix(#000, @content_view_bg, 0.875); \
|
color: mix(#000, @content_view_bg, 0.875); \
|
||||||
border-color: mix(#fff, @content_view_bg, 0.5); \
|
border-color: mix(#fff, @content_view_bg, 0.5); \
|
||||||
} \
|
} \
|
||||||
|
fiv-browser.item.symbolic, \
|
||||||
|
fiv-browser.item.symbolic:selected, \
|
||||||
|
fiv-browser.item.symbolic:backdrop { \
|
||||||
|
color: shade(@theme_bg_color, 0.875); \
|
||||||
|
border-color: transparent; \
|
||||||
|
} \
|
||||||
fiv-browser.item.symbolic { \
|
fiv-browser.item.symbolic { \
|
||||||
border-color: transparent; color: shade(@theme_bg_color, 0.875); \
|
background-blend-mode: color; \
|
||||||
background: @theme_bg_color; background-image: none; \
|
background: @theme_bg_color; background-image: none; \
|
||||||
} \
|
} \
|
||||||
|
fiv-browser.item.symbolic:selected { \
|
||||||
|
color: @theme_selected_bg_color; background-image: linear-gradient(0, \
|
||||||
|
@theme_selected_bg_color, @theme_selected_bg_color); \
|
||||||
|
} \
|
||||||
|
fiv-browser.item.symbolic:selected:not(:focus) { \
|
||||||
|
color: @fiv-semiselected; background-image: linear-gradient(0, \
|
||||||
|
@fiv-semiselected, @fiv-semiselected); \
|
||||||
|
} \
|
||||||
.fiv-information label { padding: 0 4px; }";
|
.fiv-information label { padding: 0 4px; }";
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1709,11 +1734,6 @@ main(int argc, char *argv[])
|
|||||||
G_CALLBACK(on_item_activated), NULL);
|
G_CALLBACK(on_item_activated), NULL);
|
||||||
gtk_container_add(GTK_CONTAINER(g.browser_scroller), g.browser);
|
gtk_container_add(GTK_CONTAINER(g.browser_scroller), g.browser);
|
||||||
|
|
||||||
// Christ, no, do not scroll all the way to the top on focus.
|
|
||||||
GtkWidget *browser_port = gtk_bin_get_child(GTK_BIN(g.browser_scroller));
|
|
||||||
gtk_container_set_focus_hadjustment(GTK_CONTAINER(browser_port), NULL);
|
|
||||||
gtk_container_set_focus_vadjustment(GTK_CONTAINER(browser_port), NULL);
|
|
||||||
|
|
||||||
g.browser_sidebar = make_browser_sidebar(g.model);
|
g.browser_sidebar = make_browser_sidebar(g.model);
|
||||||
g.browser_paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
|
g.browser_paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
|
||||||
gtk_paned_add1(GTK_PANED(g.browser_paned), g.browser_sidebar);
|
gtk_paned_add1(GTK_PANED(g.browser_paned), g.browser_sidebar);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user