1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/*
* Common callbacks for spinbuttons
*
* Authors:
* bulia byak <bulia@users.sourceforge.net>
*
* Copyright (C) 2003 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "../event-context.h"
#include "sp-widget.h"
#include "widget-sizes.h"
#include "spinbutton-events.h"
gboolean
spinbutton_focus_in (GtkWidget *w, GdkEventKey */*event*/, gpointer /*data*/)
{
gdouble *ini;
ini = (gdouble *) g_object_get_data(G_OBJECT (w), "ini");
if (ini) g_free (ini); // free the old value if any
// retrieve the value
ini = g_new (gdouble, 1);
*ini = gtk_spin_button_get_value (GTK_SPIN_BUTTON(w));
// remember it
g_object_set_data (G_OBJECT (w), "ini", ini);
return FALSE; // I didn't consume the event
}
void
spinbutton_undo (GtkWidget *w)
{
gdouble *ini = (gdouble *) g_object_get_data(G_OBJECT (w), "ini");
if (ini) {
gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), *ini);
}
}
void
spinbutton_defocus (GtkWidget *container)
{
// defocus spinbuttons by moving focus to the canvas, unless "stay" is on
gboolean stay = GPOINTER_TO_INT(g_object_get_data(G_OBJECT (container), "stay"));
if (stay) {
g_object_set_data (G_OBJECT (container), "stay", GINT_TO_POINTER (FALSE));
} else {
GtkWidget *canvas = (GtkWidget *) g_object_get_data(G_OBJECT (container), "dtw");
if (canvas) {
gtk_widget_grab_focus (GTK_WIDGET(canvas));
}
}
}
gboolean spinbutton_keypress(GtkWidget *w, GdkEventKey *event, gpointer data)
{
SPWidget *spw = SP_WIDGET(data);
gdouble v;
gdouble step;
gdouble page;
switch (get_group0_keyval (event)) {
case GDK_KEY_Escape: // defocus
spinbutton_undo (w);
spinbutton_defocus(GTK_WIDGET(spw));
return TRUE; // I consumed the event
break;
case GDK_KEY_Return: // defocus
case GDK_KEY_KP_Enter:
spinbutton_defocus (GTK_WIDGET(spw));
return TRUE; // I consumed the event
break;
case GDK_KEY_Tab:
case GDK_KEY_ISO_Left_Tab:
// set the flag meaning "do not leave toolbar when changing value"
g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE));
return FALSE; // I didn't consume the event
break;
// The following keys are processed manually because GTK implements them in strange ways
// (increments start with double step value and seem to grow as you press the key continuously)
case GDK_KEY_Up:
case GDK_KEY_KP_Up:
g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE));
v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w));
gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page);
v += step;
gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v);
return TRUE; // I consumed the event
break;
case GDK_KEY_Down:
case GDK_KEY_KP_Down:
g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE));
v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w));
gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page);
v -= step;
gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v);
return TRUE; // I consumed the event
break;
case GDK_KEY_Page_Up:
case GDK_KEY_KP_Page_Up:
g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE));
v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w));
gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page);
v += page;
gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v);
return TRUE; // I consumed the event
break;
case GDK_KEY_Page_Down:
case GDK_KEY_KP_Page_Down:
g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE));
v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w));
gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page);
v -= page;
gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v);
return TRUE; // I consumed the event
break;
case GDK_KEY_z:
case GDK_KEY_Z:
g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE));
if (event->state & GDK_CONTROL_MASK) {
spinbutton_undo (w);
return TRUE; // I consumed the event
}
break;
default:
return FALSE;
break;
}
return FALSE; // I didn't consume the event
}
|