diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2021-12-20 14:25:59 +0100 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2021-12-20 16:04:50 +0100 |
commit | 9ba3679e89a0c760c016a541557528cfbea59f20 (patch) | |
tree | bd30ecabf64b3b1649c03bb8c78c33f2fa535568 | |
parent | 6a61d01f4de8ae86199c3ca9cfb19c063784ee12 (diff) | |
download | fiv-9ba3679e89a0c760c016a541557528cfbea59f20.tar.gz fiv-9ba3679e89a0c760c016a541557528cfbea59f20.tar.xz fiv-9ba3679e89a0c760c016a541557528cfbea59f20.zip |
Make use of GtkShortcutsWindow
-rw-r--r-- | fastiv.c | 174 |
1 files changed, 172 insertions, 2 deletions
@@ -52,6 +52,146 @@ exit_fatal(const gchar *format, ...) exit(EXIT_FAILURE); } +// --- Help -------------------------------------------------------------------- +// Fuck XML, this can be easily represented in static structures. +// Though it would be nice if the accelerators could be customized. + +struct key { + const char *accelerator; + const char *title; +}; + +struct key_group { + const char *title; + const struct key *keys; +}; + +struct key_section { + const char *title; + const char *section_name; + const struct key_group *groups; +}; + +static struct key help_keys_general[] = { + {"F1 <control>F1", "Show this list of shortcuts"}, + {"F11 f", "Toggle fullscreen view"}, + {"<alt><shift>d", "Toggle dark theme variant"}, + {"q <control>q", "Exit the program"}, + {"Escape <control>w", "Exit the program"}, + {} +}; + +static struct key_section help_keys[] = { + {"Browser", "browser", (struct key_group[]) { + {"General", help_keys_general}, + {"View", (struct key[]) { + {"F9", "Toggle navigation sidebar"}, + {} + }}, + {"Navigation", (struct key[]) { + {"<control>l", "Open location..."}, + {"<control>n", "Open a new window"}, + {"<alt>Left", "Go back in history"}, + {"<alt>Right", "Go forward in history"}, + {"<alt>Up", "Go to parent directory"}, + {"F5 r <control>r", "Refresh"}, + {} + }}, + {} + }}, + {"View", "view", (struct key_group[]) { + {"General", help_keys_general}, + {"View", (struct key[]) { + {"F8", "Toggle toolbar"}, + {} + }}, + {"Navigation", (struct key[]) { + {"<control>l", "Open location..."}, + {"<control>n", "Open a new window"}, + {"Left Up Page_Up", "Previous image"}, + {"Right Down Page_Down", "Next image"}, + {"Return <alt>Left", "Return to browser"}, + {} + }}, + {"Zoom", (struct key[]) { + {"<control>0", "Set zoom to 100%"}, + {"1...9", "Set zoom to N:1"}, + {"plus <control>plus", "Zoom in"}, + {"minus <control>minus", "Zoom out"}, + {} + }}, + {"Orientation", (struct key[]) { + {"less", "Rotate anticlockwise"}, + {"equal", "Mirror"}, + {"greater", "Rotate clockwise"}, + {} + }}, + {"Control", (struct key[]) { + {"bracketleft", "Previous page"}, + {"bracketright", "Next page"}, + {"braceleft", "Previous frame"}, + {"braceright", "Next frame"}, + {"space", "Toggle playback"}, + {} + }}, + {"Configuration", (struct key[]) { + {"x", "Toggle scale to fit"}, + {"i", "Toggle smooth scaling"}, + {"t", "Toggle transparency highlighting"}, + {} + }}, + {"Tools", (struct key[]) { + {"<control>p", "Print..."}, + {"<control>s", "Save page as..."}, + {"<control><shift>s", "Save frame as..."}, + {} + }}, + {} + }}, + {} +}; + +static GtkWidget * +make_key(const struct key *key) +{ + return gtk_widget_new(GTK_TYPE_SHORTCUTS_SHORTCUT, + "title", key->title, + "shortcut-type", GTK_SHORTCUT_ACCELERATOR, + "accelerator", key->accelerator, NULL); +} + +static GtkWidget * +make_key_group(const struct key_group *group) +{ + GtkWidget *widget = gtk_widget_new( + GTK_TYPE_SHORTCUTS_GROUP, "title", group->title, NULL); + for (const struct key *p = group->keys; p->title; p++) + gtk_container_add(GTK_CONTAINER(widget), make_key(p)); + return widget; +} + +static GtkWidget * +make_key_section(const struct key_section *section) +{ + GtkWidget *widget = gtk_widget_new(GTK_TYPE_SHORTCUTS_SECTION, + "title", section->title, "section-name", section->section_name, NULL); + for (const struct key_group *p = section->groups; p->title; p++) + gtk_container_add(GTK_CONTAINER(widget), make_key_group(p)); + return widget; +} + +static GtkWidget * +make_key_window(void) +{ + GtkWidget *window = gtk_widget_new(GTK_TYPE_SHORTCUTS_WINDOW, NULL); + for (const struct key_section *p = help_keys; p->title; p++) { + GtkWidget *section = make_key_section(p); + gtk_widget_show_all(section); + gtk_container_add(GTK_CONTAINER(window), section); + } + return window; +} + // --- Main -------------------------------------------------------------------- // TODO(p): See if it's possible to give separators room to shrink @@ -535,6 +675,31 @@ on_window_state_event(G_GNUC_UNUSED GtkWidget *widget, gtk_image_set_from_icon_name(image, name, GTK_ICON_SIZE_BUTTON); } +static void +on_help_destroyed(GtkWidget *window, GtkWidget **storage) +{ + g_return_if_fail(*storage == window); + *storage = NULL; +} + +static void +show_help_shortcuts(void) +{ + static GtkWidget *window; + if (!window) { + window = make_key_window(); + g_signal_connect( + window, "destroy", G_CALLBACK(on_help_destroyed), &window); + } + + g_object_set(window, "section-name", + gtk_stack_get_visible_child(GTK_STACK(g.stack)) == g.view_box + ? "view" + : "browser", + NULL); + gtk_widget_show(window); +} + // Cursor keys, e.g., simply cannot be bound through accelerators // (and GtkWidget::keynav-failed would arguably be an awful solution). // @@ -579,6 +744,10 @@ on_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event, case GDK_KEY_w: gtk_widget_destroy(g.window); return TRUE; + + case GDK_KEY_F1: + show_help_shortcuts(); + return TRUE; } break; case GDK_MOD1_MASK: @@ -615,13 +784,15 @@ on_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event, 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; case GDK_KEY_F9: gtk_widget_set_visible(g.browser_sidebar, !gtk_widget_is_visible(g.browser_sidebar)); @@ -657,7 +828,6 @@ on_key_press_view(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event, case GDK_KEY_Right: case GDK_KEY_Down: case GDK_KEY_Page_Down: - case GDK_KEY_space: on_next(); return TRUE; |