Commit a20f5d22 authored by Paolo Bacchilega's avatar Paolo Bacchilega

added ability to define custom shortcuts for a window

parent 313f7bf7
......@@ -3716,41 +3716,19 @@ static gboolean
gth_browser_file_list_key_press_cb (GthBrowser *browser,
GdkEventKey *event)
{
gboolean result = FALSE;
guint modifiers;
guint modifiers;
gboolean activated;
modifiers = gtk_accelerator_get_default_mod_mask ();
activated = gth_window_activate_shortcut (GTH_WINDOW (browser),
GTH_SHORTCUT_CONTEXT_BROWSER,
event->keyval,
(event->state & modifiers));
if ((event->state & modifiers) == 0) {
switch (event->keyval) {
case GDK_KEY_f:
gth_browser_fullscreen (browser);
result = TRUE;
break;
case GDK_KEY_e:
if (browser->priv->viewer_page != NULL)
gth_browser_show_viewer_tools (GTH_BROWSER (browser));
result = TRUE;
break;
if (! activated)
activated = gth_hook_invoke_get ("gth-browser-file-list-key-press", browser, event) != NULL;
case GDK_KEY_i:
if (gth_window_get_action_state (GTH_WINDOW (browser), "browser-properties"))
gth_browser_hide_sidebar (browser);
else
gth_browser_show_file_properties (browser);
result = TRUE;
break;
default:
break;
}
}
if (! result)
result = gth_hook_invoke_get ("gth-browser-file-list-key-press", browser, event) != NULL;
return result;
return activated;
}
......@@ -5657,56 +5635,21 @@ gboolean
gth_browser_viewer_key_press_cb (GthBrowser *browser,
GdkEventKey *event)
{
guint modifiers;
guint modifiers;
gboolean activated;
g_return_val_if_fail (event != NULL, FALSE);
modifiers = gtk_accelerator_get_default_mod_mask ();
if ((event->state & modifiers) == 0) {
switch (event->keyval) {
case GDK_KEY_Page_Up:
case GDK_KEY_KP_Page_Up:
case GDK_KEY_BackSpace:
gth_browser_show_prev_image (browser, FALSE, FALSE);
return TRUE;
case GDK_KEY_Page_Down:
case GDK_KEY_KP_Page_Down:
case GDK_KEY_space:
gth_browser_show_next_image (browser, FALSE, FALSE);
return TRUE;
activated = gth_window_activate_shortcut (GTH_WINDOW (browser),
GTH_SHORTCUT_CONTEXT_VIEWER,
event->keyval,
(event->state & modifiers));
case GDK_KEY_Home:
case GDK_KEY_KP_Home:
gth_browser_show_first_image (browser, FALSE, FALSE);
return TRUE;
case GDK_KEY_End:
case GDK_KEY_KP_End:
gth_browser_show_last_image (browser, FALSE, FALSE);
return TRUE;
case GDK_KEY_e:
if (browser->priv->viewer_sidebar != GTH_SIDEBAR_STATE_TOOLS)
gth_browser_show_viewer_tools (browser);
else
gth_browser_hide_sidebar (browser);
return TRUE;
case GDK_KEY_i:
gth_browser_toggle_properties_on_screen (browser);
return TRUE;
if (! activated && gtk_widget_get_realized (browser->priv->file_list))
activated = gth_hook_invoke_get ("gth-browser-file-list-key-press", browser, event) != NULL;
case GDK_KEY_f:
gth_browser_fullscreen (browser);
return TRUE;
}
}
if (gtk_widget_get_realized (browser->priv->file_list))
return gth_hook_invoke_get ("gth-browser-file-list-key-press", browser, event) != NULL;
else
return FALSE;
return activated;
}
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* GThumb
*
* Copyright (C) 2019 The Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "gth-shortcut.h"
GthShortcut *
gth_shortcut_new (void)
{
GthShortcut *shortcut;
shortcut = g_new (GthShortcut, 1);
shortcut->action_name = NULL;
shortcut->description = NULL;
shortcut->context = 0;
shortcut->category = 0;
shortcut->default_accelerator = NULL;
shortcut->accelerator = NULL;
shortcut->label = NULL;
shortcut->keyval = 0;
shortcut->modifiers = 0;
return shortcut;
}
GthShortcut *
gth_shortcut_dup (const GthShortcut *shortcut)
{
GthShortcut *new_shortcut;
new_shortcut = gth_shortcut_new ();
new_shortcut->action_name = g_strdup (shortcut->action_name);
new_shortcut->description = g_strdup (shortcut->description);
new_shortcut->context = shortcut->context;
new_shortcut->category = shortcut->category;
new_shortcut->default_accelerator = g_strdup (shortcut->default_accelerator);
gth_shortcut_set_name (new_shortcut, shortcut->accelerator);
return new_shortcut;
}
void
gth_shortcut_free (GthShortcut *shortcut)
{
g_free (shortcut->action_name);
g_free (shortcut->description);
g_free (shortcut->default_accelerator);
g_free (shortcut->accelerator);
g_free (shortcut->label);
g_free (shortcut);
}
void
gth_shortcut_set_name (GthShortcut *shortcut,
const char *accelerator)
{
guint keyval;
GdkModifierType modifiers;
keyval = 0;
modifiers = 0;
if (accelerator != NULL)
gtk_accelerator_parse (accelerator, &keyval, &modifiers);
gth_shortcut_set_key (shortcut, keyval, modifiers);
}
void
gth_shortcut_set_key (GthShortcut *shortcut,
guint keyval,
GdkModifierType modifiers)
{
g_free (shortcut->accelerator);
g_free (shortcut->label);
shortcut->keyval = keyval;
shortcut->modifiers = modifiers;
shortcut->accelerator = gtk_accelerator_name (shortcut->keyval, shortcut->modifiers);
shortcut->label = gtk_accelerator_get_label (shortcut->keyval, shortcut->modifiers);
}
GthShortcut *
gth_shortcut_array_find (GPtrArray *shortcuts_v,
int context,
guint keycode,
GdkModifierType modifiers)
{
int i;
for (i = 0; i < shortcuts_v->len; i++) {
GthShortcut *shortcut = g_ptr_array_index (shortcuts_v, i);
if (((shortcut->context & context) == context)
&& (shortcut->keyval == keycode)
&& (shortcut->modifiers == modifiers))
{
return shortcut;
}
}
return NULL;
}
gboolean
gth_shortcut_valid (guint keycode,
GdkModifierType modifiers)
{
switch (keycode) {
case GDK_KEY_Escape:
case GDK_KEY_Tab:
return FALSE;
case GDK_KEY_Left:
case GDK_KEY_Right:
case GDK_KEY_Up:
case GDK_KEY_Down:
return TRUE;
default:
return gtk_accelerator_valid (keycode, modifiers);
}
return FALSE;
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* GThumb
*
* Copyright (C) 2019 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GTH_SHORTCUT_H
#define GTH_SHORTCUT_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTH_SHORTCUT_CONTEXT_INTERNAL -1
#define GTH_SHORTCUT_CATEGORY_HIDDEN -1
typedef struct {
char *action_name;
char *description;
int context;
int category;
char *default_accelerator;
char *accelerator;
char *label;
guint keyval;
GdkModifierType modifiers;
} GthShortcut;
GthShortcut * gth_shortcut_new (void);
GthShortcut * gth_shortcut_dup (const GthShortcut *shortcut);
void gth_shortcut_free (GthShortcut *shortcut);
void gth_shortcut_set_key (GthShortcut *shortcut,
guint keyval,
GdkModifierType modifiers);
void gth_shortcut_set_name (GthShortcut *shortcut,
const char *name);
GthShortcut * gth_shortcut_array_find (GPtrArray *shortcuts_v,
int context,
guint keycode,
GdkModifierType modifiers);
gboolean gth_shortcut_valid (guint keycode,
GdkModifierType modifiers);
G_END_DECLS
#endif /* GTH_SHORTCUT_H */
......@@ -21,6 +21,7 @@
#include <config.h>
#include <gtk/gtk.h>
#include "glib-utils.h"
#include "gth-window.h"
#include "gth-window-title.h"
#include "gtk-utils.h"
......@@ -54,6 +55,8 @@ struct _GthWindowPrivate {
GthWindowSize *window_size;
GtkWindowGroup *window_group;
GtkAccelGroup *accel_group;
GHashTable *shortcuts;
GPtrArray *shortcuts_v;
};
......@@ -249,6 +252,8 @@ gth_window_finalize (GObject *object)
g_free (window->priv->window_size);
g_object_unref (window->priv->window_group);
g_object_unref (window->priv->accel_group);
g_hash_table_unref (window->priv->shortcuts);
g_ptr_array_free (window->priv->shortcuts_v, TRUE);
G_OBJECT_CLASS (gth_window_parent_class)->finalize (object);
}
......@@ -399,6 +404,9 @@ gth_window_init (GthWindow *window)
window->priv->accel_group = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accel_group);
window->priv->shortcuts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
window->priv->shortcuts_v = g_ptr_array_new_with_free_func ((GDestroyNotify) gth_shortcut_free);
gtk_window_set_application (GTK_WINDOW (window), Main_Application);
}
......@@ -692,6 +700,17 @@ gth_window_get_accel_group (GthWindow *window)
}
static void
_gth_window_add_shortcut (GthWindow *window,
GthShortcut *shorcut)
{
g_hash_table_insert (window->priv->shortcuts,
g_strdup (shorcut->action_name),
GINT_TO_POINTER (1));
g_ptr_array_add (window->priv->shortcuts_v, shorcut);
}
void
gth_window_add_accelerators (GthWindow *window,
const GthAccelerator *accelerators,
......@@ -703,12 +722,20 @@ gth_window_add_accelerators (GthWindow *window,
accel_group = gth_window_get_accel_group (window);
for (i = 0; i < n_accelerators; i++) {
const GthAccelerator *acc = accelerators + i;
GthShortcut *shortcut;
_gtk_window_add_accelerator_for_action (GTK_WINDOW (window),
accel_group,
acc->action_name,
acc->accelerator,
NULL);
shortcut = gth_shortcut_new ();
shortcut->action_name = g_strdup (acc->action_name);
shortcut->context = GTH_SHORTCUT_CONTEXT_INTERNAL;
shortcut->category = GTH_SHORTCUT_CATEGORY_HIDDEN;
gth_shortcut_set_name (shortcut, acc->accelerator);
_gth_window_add_shortcut (window, shortcut);
}
}
......@@ -765,3 +792,61 @@ gth_window_change_action_state (GthWindow *window,
g_variant_unref (old_state);
g_variant_unref (new_state);
}
void
gth_window_add_shortcuts (GthWindow *window,
const GthShortcut *shortcuts,
int n_shortcuts)
{
int i;
for (i = 0; i < n_shortcuts; i++) {
const GthShortcut *shortcut = shortcuts + i;
GthShortcut *new_shortcut;
new_shortcut = gth_shortcut_dup (shortcut);
gth_shortcut_set_name (new_shortcut, shortcut->default_accelerator);
_gth_window_add_shortcut (window, new_shortcut);
}
}
GPtrArray *
gth_window_get_shortcuts (GthWindow *window)
{
g_return_val_if_fail (GTH_IS_WINDOW (window), NULL);
return window->priv->shortcuts_v;
}
gboolean
gth_window_activate_shortcut (GthWindow *window,
int context,
guint keycode,
GdkModifierType modifiers)
{
gboolean activated = FALSE;
GthShortcut *shortcut;
shortcut = gth_shortcut_array_find (window->priv->shortcuts_v, context, keycode, modifiers);
if (shortcut != NULL) {
GAction *action;
action = g_action_map_lookup_action (G_ACTION_MAP (window), shortcut->action_name);
if (action != NULL) {
GVariant *variant;
variant = g_action_get_state (action);
g_action_activate (action, variant);
activated = TRUE;
if (variant != NULL)
g_variant_unref (variant);
}
}
return activated;
}
......@@ -24,6 +24,7 @@
#include <gtk/gtk.h>
#include "gtk-utils.h"
#include "gth-shortcut.h"
G_BEGIN_DECLS
......@@ -120,6 +121,14 @@ gboolean gth_window_get_action_state (GthWindow *window,
void gth_window_change_action_state (GthWindow *window,
const char *action_name,
gboolean value);
void gth_window_add_shortcuts (GthWindow *window,
const GthShortcut *shortcuts,
int n_shortcuts);
GPtrArray * gth_window_get_shortcuts (GthWindow *window);
gboolean gth_window_activate_shortcut (GthWindow *window,
int context,
guint keycode,
GdkModifierType modifiers);
G_END_DECLS
......
......@@ -80,6 +80,7 @@ public_header_files = [
'gth-save-file-data-task.h',
'gth-save-image-task.h',
'gth-screensaver.h',
'gth-shortcut.h',
'gth-sidebar.h',
'gth-sidebar-section.h',
'gth-statusbar.h',
......@@ -244,6 +245,7 @@ source_files = files(
'gth-save-file-data-task.c',
'gth-save-image-task.c',
'gth-screensaver.c',
'gth-shortcut.c',
'gth-sidebar.c',
'gth-sidebar-section.c',
'gth-statusbar.c',
......
......@@ -130,6 +130,27 @@ typedef enum /*< skip >*/ {
} GthColorSpace;
typedef enum {
GTH_SHORTCUT_CONTEXT_BROWSER = 1 << 1,
GTH_SHORTCUT_CONTEXT_VIEWER = 1 << 2,
GTH_SHORTCUT_CONTEXT_SLIDESHOW = 1 << 3,
/* aggregated values */
GTH_SHORTCUT_CONTEXT_BROWSER_VIEWER = (GTH_SHORTCUT_CONTEXT_BROWSER | GTH_SHORTCUT_CONTEXT_VIEWER),
GTH_SHORTCUT_CONTEXT_ANY = (GTH_SHORTCUT_CONTEXT_BROWSER | GTH_SHORTCUT_CONTEXT_VIEWER | GTH_SHORTCUT_CONTEXT_SLIDESHOW),
} GthShortcutContext;
typedef enum {
GTH_SHORTCUT_CATEGORY_UI,
GTH_SHORTCUT_CATEGORY_FILE_NAVIGATION,
GTH_SHORTCUT_CATEGORY_FILE_EDIT,
GTH_SHORTCUT_CATEGORY_IMAGE_VIEW,
GTH_SHORTCUT_CATEGORY_IMAGE_EDIT,
GTH_SHORTCUT_CATEGORY_SLIDESHOW
} GthShortcutCategory;
typedef void (*DataFunc) (gpointer user_data);
typedef void (*ReadyFunc) (GError *error,
gpointer user_data);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment