Compare commits

...

5 Commits

5 changed files with 61 additions and 27 deletions

View File

@ -1019,11 +1019,19 @@ fiv_browser_realize(GtkWidget *widget)
static void
fiv_browser_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
{
FivBrowser *self = FIV_BROWSER(widget);
GTK_WIDGET_CLASS(fiv_browser_parent_class)
->size_allocate(widget, allocation);
// TODO(p): Update adjustments so that blank space is avoided.
relayout(FIV_BROWSER(widget), allocation->width);
int height = relayout(FIV_BROWSER(widget), allocation->width);
// Avoid fresh blank space.
if (self->vadjustment) {
double y1 = gtk_adjustment_get_value(self->vadjustment);
double ph = gtk_adjustment_get_page_size(self->vadjustment);
if (y1 + ph > height)
gtk_adjustment_set_value(self->vadjustment, height - ph);
}
}
static gboolean
@ -1542,12 +1550,9 @@ on_model_files_changed(FivIoModel *model, FivBrowser *self)
{
g_return_if_fail(model == self->model);
int selected = -1;
gchar *selected_uri = NULL;
if (self->selected) {
if (self->selected)
selected_uri = g_strdup(self->selected->uri);
self->selected = NULL;
}
// TODO(p): Later implement arguments.
thumbnailers_abort(self);
@ -1558,16 +1563,12 @@ on_model_files_changed(FivIoModel *model, FivBrowser *self)
for (guint i = 0; i < files->len; i++) {
g_array_append_val(self->entries,
((Entry) {.thumbnail = NULL, .uri = files->pdata[i]}));
if (!g_strcmp0(selected_uri, files->pdata[i]))
selected = i;
files->pdata[i] = NULL;
}
g_ptr_array_free(files, TRUE);
// Beware that the pointer may shift with the storage.
fiv_browser_select(self, selected_uri);
g_free(selected_uri);
if (selected >= 0)
self->selected = &g_array_index(self->entries, Entry, selected);
reload_thumbnails(self);
thumbnailers_start(self);
@ -1586,3 +1587,24 @@ fiv_browser_new(FivIoModel *model)
on_model_files_changed(self->model, self);
return GTK_WIDGET(self);
}
void
fiv_browser_select(FivBrowser *self, const char *uri)
{
g_return_if_fail(FIV_IS_BROWSER(self));
self->selected = NULL;
gtk_widget_queue_draw(GTK_WIDGET(self));
if (!uri)
return;
for (guint i = 0; i < self->entries->len; i++) {
const Entry *entry = &g_array_index(self->entries, Entry, i);
if (!g_strcmp0(entry->uri, uri)) {
self->selected = entry;
break;
}
}
// TODO(p): Scroll to selection.
}

View File

@ -25,3 +25,4 @@
G_DECLARE_FINAL_TYPE(FivBrowser, fiv_browser, FIV, BROWSER, GtkWidget)
GtkWidget *fiv_browser_new(FivIoModel *model);
void fiv_browser_select(FivBrowser *self, const char *uri);

View File

@ -1064,11 +1064,14 @@ fiv_view_class_init(FivViewClass *klass)
bind(bs, GDK_KEY_plus, GDK_CONTROL_MASK, FIV_VIEW_COMMAND_ZOOM_IN);
bind(bs, GDK_KEY_minus, GDK_CONTROL_MASK, FIV_VIEW_COMMAND_ZOOM_OUT);
bind(bs, GDK_KEY_p, GDK_CONTROL_MASK, FIV_VIEW_COMMAND_PRINT);
bind(bs, GDK_KEY_r, GDK_CONTROL_MASK, FIV_VIEW_COMMAND_RELOAD);
bind(bs, GDK_KEY_s, GDK_CONTROL_MASK, FIV_VIEW_COMMAND_SAVE_PAGE);
bind(bs, GDK_KEY_s, GDK_MOD1_MASK, FIV_VIEW_COMMAND_SAVE_FRAME);
bind(bs, GDK_KEY_Return, GDK_MOD1_MASK, FIV_VIEW_COMMAND_INFO);
// The scale-to-fit binding is from gThumb, which has more such modes.
bind(bs, GDK_KEY_F5, 0, FIV_VIEW_COMMAND_RELOAD);
bind(bs, GDK_KEY_r, 0, FIV_VIEW_COMMAND_RELOAD);
bind(bs, GDK_KEY_plus, 0, FIV_VIEW_COMMAND_ZOOM_IN);
bind(bs, GDK_KEY_minus, 0, FIV_VIEW_COMMAND_ZOOM_OUT);
bind(bs, GDK_KEY_w, 0, FIV_VIEW_COMMAND_FIT_WIDTH);
@ -1203,6 +1206,9 @@ fiv_view_command(FivView *self, FivViewCommand command)
return;
switch (command) {
break; case FIV_VIEW_COMMAND_RELOAD:
reload(self);
break; case FIV_VIEW_COMMAND_ROTATE_LEFT:
self->orientation = view_left[self->orientation];
gtk_widget_queue_resize(widget);

View File

@ -28,6 +28,8 @@ gboolean fiv_view_open(FivView *self, const gchar *uri, GError **error);
// And this is how you avoid glib-mkenums.
typedef enum _FivViewCommand {
#define FIV_VIEW_COMMANDS(XX) \
XX(FIV_VIEW_COMMAND_RELOAD, "reload") \
\
XX(FIV_VIEW_COMMAND_ROTATE_LEFT, "rotate-left") \
XX(FIV_VIEW_COMMAND_MIRROR, "mirror") \
XX(FIV_VIEW_COMMAND_ROTATE_RIGHT, "rotate-right") \

35
fiv.c
View File

@ -84,6 +84,7 @@ static struct key_group help_keys_browser[] = {
{"General", help_keys_general},
{"View", (struct key[]) {
{"F9", "Toggle navigation sidebar"},
{"F5 r <control>r", "Refresh"},
{"h <control>h", "Toggle hiding unsupported files"},
{}
}},
@ -94,7 +95,7 @@ static struct key_group help_keys_browser[] = {
{"<alt>Right", "Go forward in history"},
{"<alt>Up", "Go to parent directory"},
{"<alt>Home", "Go home"},
{"F5 r <control>r", "Refresh"},
{"Return", "Open selected item"},
{}
}},
{}
@ -104,6 +105,7 @@ static struct key_group help_keys_view[] = {
{"General", help_keys_general},
{"View", (struct key[]) {
{"F8", "Toggle toolbar"},
{"F5 r <control>r", "Reload"},
{}
}},
{"Navigation", (struct key[]) {
@ -404,7 +406,7 @@ show_about_dialog(GtkWidget *parent)
GtkWidget *website = gtk_label_new(NULL);
gtk_label_set_selectable(GTK_LABEL(website), TRUE);
const char *url = "https://git.janouch.name/p/fiv";
const char *url = "https://git.janouch.name/p/" PROJECT_NAME;
gchar *link = g_strdup_printf("<a href='%s'>%s</a>", url, url);
gtk_label_set_markup(GTK_LABEL(website), link);
g_free(link);
@ -878,11 +880,12 @@ open_any_file(GFile *file, gboolean force_browser)
} else if (type == G_FILE_TYPE_DIRECTORY) {
load_directory(uri);
} else if (force_browser) {
// GNOME, e.g., invokes this as a hint to focus the particular file,
// which we can't currently do yet.
// GNOME, e.g., invokes this as a hint to focus the particular file.
gchar *parent = parent_uri(file);
load_directory(parent);
g_free(parent);
fiv_browser_select(FIV_BROWSER(g.browser), uri);
} else {
open(uri);
}
@ -1044,10 +1047,6 @@ on_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
case GDK_KEY_o:
on_open();
return TRUE;
case GDK_KEY_r:
// TODO(p): Reload the image instead, if it's currently visible.
load_directory(NULL);
return TRUE;
case GDK_KEY_q:
case GDK_KEY_w:
gtk_widget_destroy(g.window);
@ -1087,16 +1086,9 @@ on_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
case GDK_KEY_q:
gtk_widget_destroy(g.window);
return TRUE;
case GDK_KEY_o:
on_open();
return TRUE;
case GDK_KEY_F5:
case GDK_KEY_r:
// TODO(p): See the comment for C-r above.
load_directory(NULL);
return TRUE;
case GDK_KEY_F1:
show_help_shortcuts();
return TRUE;
@ -1104,7 +1096,6 @@ on_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
gtk_widget_set_visible(g.browser_sidebar,
!gtk_widget_is_visible(g.browser_sidebar));
return TRUE;
case GDK_KEY_F11:
case GDK_KEY_f:
toggle_fullscreen();
@ -1140,6 +1131,7 @@ on_key_press_view(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
case GDK_KEY_Return:
switch_to_browser();
fiv_browser_select(FIV_BROWSER(g.browser), g.uri);
return TRUE;
}
}
@ -1152,6 +1144,13 @@ on_key_press_browser_paned(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
{
// TODO(p): Consider replicating more GtkFileChooserWidget bindings.
switch (event->state & gtk_accelerator_get_default_mod_mask()) {
case GDK_CONTROL_MASK:
switch (event->keyval) {
case GDK_KEY_r:
load_directory(NULL);
return TRUE;
}
break;
case GDK_MOD1_MASK:
switch (event->keyval) {
case GDK_KEY_Up: {
@ -1175,6 +1174,10 @@ on_key_press_browser_paned(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
case GDK_KEY_h:
gtk_button_clicked(GTK_BUTTON(g.funnel));
return TRUE;
case GDK_KEY_F5:
case GDK_KEY_r:
load_directory(NULL);
return TRUE;
}
}
return FALSE;