mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 05:00:20 +00:00
First step towards grabbing keys and handling them ourselves
This commit steals the cursor up and down keys away from gtk so regardless where gtk thinks the focus may be, we can still use the keys to change between dives. In the current UI design where all editing happens in separate windows this works as expected, as we only grab the keys for the main window. If we manage to re-enable in-place editing then we need to make sure that this doesn't cause problems (as gtk uses up/down for the ability to change drop down selections in combo boxes or values in spin buttons. So we must make sure that we stop stealing these keys once we start editing something (in which case simply switching to the next/prev dive wouldn't be a good thing, anyway). Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
d720e133d8
commit
91ca0d2cf6
3 changed files with 120 additions and 0 deletions
99
divelist.c
99
divelist.c
|
@ -2627,3 +2627,102 @@ void remove_autogen_trips()
|
||||||
remove_dive_from_trip(dive);
|
remove_dive_from_trip(dive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct iteridx {
|
||||||
|
int idx;
|
||||||
|
GtkTreeIter *iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean iter_has_idx(GtkTreeModel *model, GtkTreePath *path,
|
||||||
|
GtkTreeIter *iter, gpointer _data)
|
||||||
|
{
|
||||||
|
struct iteridx *iteridx = _data;
|
||||||
|
int idx;
|
||||||
|
/* Get the dive number */
|
||||||
|
gtk_tree_model_get(model, iter, DIVE_INDEX, &idx, -1);
|
||||||
|
if (idx == iteridx->idx) {
|
||||||
|
iteridx->iter = gtk_tree_iter_copy(iter);
|
||||||
|
return TRUE; /* end foreach */
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkTreeIter *get_iter_from_idx(int idx)
|
||||||
|
{
|
||||||
|
struct iteridx iteridx = {idx, };
|
||||||
|
gtk_tree_model_foreach(MODEL(dive_list), iter_has_idx, &iteridx);
|
||||||
|
return iteridx.iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void select_next_dive(void)
|
||||||
|
{
|
||||||
|
GtkTreeIter *nextiter;
|
||||||
|
GtkTreeIter *iter = get_iter_from_idx(selected_dive);
|
||||||
|
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view));
|
||||||
|
GtkTreePath *treepath;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (!iter)
|
||||||
|
return;
|
||||||
|
nextiter = gtk_tree_iter_copy(iter);
|
||||||
|
if (!gtk_tree_model_iter_next(MODEL(dive_list), nextiter)) {
|
||||||
|
if (!gtk_tree_model_iter_parent(MODEL(dive_list), nextiter, iter))
|
||||||
|
/* we're at the last top level node */
|
||||||
|
return;
|
||||||
|
if (!gtk_tree_model_iter_next(MODEL(dive_list), nextiter))
|
||||||
|
/* last trip */
|
||||||
|
return;
|
||||||
|
gtk_tree_model_get(MODEL(dive_list), nextiter, DIVE_INDEX, &idx, -1);
|
||||||
|
if (idx < 0) {
|
||||||
|
/* need the first child */
|
||||||
|
GtkTreeIter *parent = gtk_tree_iter_copy(nextiter);
|
||||||
|
if (! gtk_tree_model_iter_children(MODEL(dive_list), nextiter, parent))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
treepath = gtk_tree_model_get_path(MODEL(dive_list), nextiter);
|
||||||
|
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath);
|
||||||
|
gtk_tree_selection_select_iter(selection, nextiter);
|
||||||
|
gtk_tree_selection_unselect_iter(selection, iter);
|
||||||
|
gtk_tree_path_free(treepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void select_prev_dive(void)
|
||||||
|
{
|
||||||
|
GtkTreeIter previter;
|
||||||
|
GtkTreeIter *iter = get_iter_from_idx(selected_dive);
|
||||||
|
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view));
|
||||||
|
GtkTreePath *treepath;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (!iter)
|
||||||
|
return;
|
||||||
|
treepath = gtk_tree_model_get_path(MODEL(dive_list), iter);
|
||||||
|
if (!gtk_tree_path_prev(treepath)) {
|
||||||
|
if (!gtk_tree_model_iter_parent(MODEL(dive_list), &previter, iter))
|
||||||
|
/* we're at the last top level node */
|
||||||
|
return;
|
||||||
|
treepath = gtk_tree_model_get_path(MODEL(dive_list), &previter);
|
||||||
|
if (!gtk_tree_path_prev(treepath))
|
||||||
|
/* first trip */
|
||||||
|
return;
|
||||||
|
if (!gtk_tree_model_get_iter(MODEL(dive_list), &previter, treepath))
|
||||||
|
return;
|
||||||
|
gtk_tree_model_get(MODEL(dive_list), &previter, DIVE_INDEX, &idx, -1);
|
||||||
|
if (idx < 0) {
|
||||||
|
/* need the last child */
|
||||||
|
GtkTreeIter *parent = gtk_tree_iter_copy(&previter);
|
||||||
|
if (! gtk_tree_model_iter_nth_child(MODEL(dive_list), &previter, parent,
|
||||||
|
gtk_tree_model_iter_n_children(MODEL(dive_list), parent) - 1))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
treepath = gtk_tree_model_get_path(MODEL(dive_list), &previter);
|
||||||
|
} else {
|
||||||
|
if (!gtk_tree_model_get_iter(MODEL(dive_list), &previter, treepath))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath);
|
||||||
|
gtk_tree_selection_select_iter(selection, &previter);
|
||||||
|
gtk_tree_selection_unselect_iter(selection, iter);
|
||||||
|
gtk_tree_path_free(treepath);
|
||||||
|
}
|
||||||
|
|
|
@ -13,4 +13,6 @@ extern int unsaved_changes(void);
|
||||||
extern void remove_autogen_trips(void);
|
extern void remove_autogen_trips(void);
|
||||||
extern void remember_tree_state(void);
|
extern void remember_tree_state(void);
|
||||||
extern void restore_tree_state(void);
|
extern void restore_tree_state(void);
|
||||||
|
extern void select_next_dive(void);
|
||||||
|
extern void select_prev_dive(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
19
gtk-gui.c
19
gtk-gui.c
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
#include <gdk/gdkkeysyms.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -1130,6 +1131,21 @@ static void switch_page(GtkNotebook *notebook, gint arg1, gpointer user_data)
|
||||||
repaint_dive();
|
repaint_dive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, GtkWidget *divelist)
|
||||||
|
{
|
||||||
|
if (event->type != GDK_KEY_PRESS)
|
||||||
|
return FALSE;
|
||||||
|
switch (event->keyval) {
|
||||||
|
case GDK_KEY_Up:
|
||||||
|
select_prev_dive();
|
||||||
|
return TRUE;
|
||||||
|
case GDK_KEY_Down:
|
||||||
|
select_next_dive();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void init_ui(int *argcp, char ***argvp)
|
void init_ui(int *argcp, char ***argvp)
|
||||||
{
|
{
|
||||||
GtkWidget *win;
|
GtkWidget *win;
|
||||||
|
@ -1325,6 +1341,9 @@ void init_ui(int *argcp, char ***argvp)
|
||||||
nb_page = total_stats_widget();
|
nb_page = total_stats_widget();
|
||||||
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new(_("Stats")));
|
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new(_("Stats")));
|
||||||
|
|
||||||
|
/* handle some keys globally (to deal with gtk focus issues) */
|
||||||
|
g_signal_connect (G_OBJECT (win), "key_press_event", G_CALLBACK (on_key_press), dive_list);
|
||||||
|
|
||||||
gtk_widget_set_app_paintable(win, TRUE);
|
gtk_widget_set_app_paintable(win, TRUE);
|
||||||
gtk_widget_show_all(win);
|
gtk_widget_show_all(win);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue