-
Notifications
You must be signed in to change notification settings - Fork 87
/
cellrenderertextish.vala
127 lines (109 loc) · 3.57 KB
/
cellrenderertextish.vala
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
/* compile with valac -c cellrenderertextish.vala --pkg gtk+-3.0 -C -H cellrenderertextish.h */
public class CellRendererTextish : Gtk.CellRendererText {
public enum Mode { Text, Key, Popup, Combo }
public new Mode mode;
public string[] items;
public signal void key_edited(string path, Gdk.ModifierType mods, uint code);
public signal void combo_edited(string path, uint row);
private Gtk.CellEditable? cell;
public CellRendererTextish() {
mode = Mode.Text;
cell = null;
items = null;
}
public CellRendererTextish.with_items(string[] items) {
mode = Mode.Text;
cell = null;
this.items = items;
}
public override unowned Gtk.CellEditable start_editing (Gdk.Event? event, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags) {
cell = null;
if (!editable)
return cell;
switch (mode) {
case Mode.Text:
cell = base.start_editing(event, widget, path, background_area, cell_area, flags);
break;
case Mode.Key:
cell = new CellEditableAccel(this, path, widget);
break;
case Mode.Combo:
cell = new CellEditableCombo(this, path, widget, items);
break;
case Mode.Popup:
cell = new CellEditableDummy();
break;
}
return cell;
}
}
class CellEditableDummy : Gtk.EventBox, Gtk.CellEditable {
public bool editing_canceled { get; set; }
protected virtual void start_editing(Gdk.Event? event) {
editing_done();
remove_widget();
}
}
class CellEditableAccel : Gtk.EventBox, Gtk.CellEditable {
public bool editing_canceled { get; set; }
new CellRendererTextish parent;
new string path;
public CellEditableAccel(CellRendererTextish parent, string path, Gtk.Widget widget) {
this.parent = parent;
this.path = path;
editing_done.connect(on_editing_done);
Gtk.Label label = new Gtk.Label(_("Key combination..."));
label.set_alignment(0.0f, 0.5f);
add(label);
override_background_color(Gtk.StateFlags.NORMAL, widget.get_style_context().get_background_color(Gtk.StateFlags.SELECTED));
label.override_color(Gtk.StateFlags.NORMAL, widget.get_style_context().get_color(Gtk.StateFlags.SELECTED));
show_all();
}
protected virtual void start_editing(Gdk.Event? event) {
Gtk.grab_add(this);
Gdk.keyboard_grab(get_window(), false, event != null ? event.get_time() : Gdk.CURRENT_TIME);
/*
Gdk.DeviceManager dm = get_window().get_display().get_device_manager();
foreach (Gdk.Device dev in dm.list_devices(Gdk.DeviceType.SLAVE))
Gtk.device_grab_add(this, dev, true);
*/
key_press_event.connect(on_key);
}
bool on_key(Gdk.EventKey event) {
if (event.is_modifier != 0)
return true;
switch (event.keyval) {
case Gdk.Key.Super_L:
case Gdk.Key.Super_R:
case Gdk.Key.Hyper_L:
case Gdk.Key.Hyper_R:
return true;
}
Gdk.ModifierType mods = event.state & Gtk.accelerator_get_default_mod_mask();
editing_done();
remove_widget();
parent.key_edited(path, mods, event.hardware_keycode);
return true;
}
void on_editing_done() {
Gtk.grab_remove(this);
Gdk.keyboard_ungrab(Gdk.CURRENT_TIME);
/*
Gdk.DeviceManager dm = get_window().get_display().get_device_manager();
foreach (Gdk.Device dev in dm.list_devices(Gdk.DeviceType.SLAVE))
Gtk.device_grab_remove(this, dev);
*/
}
}
class CellEditableCombo : Gtk.ComboBoxText {
new CellRendererTextish parent;
new string path;
public CellEditableCombo(CellRendererTextish parent, string path, Gtk.Widget widget, string[] items) {
this.parent = parent;
this.path = path;
foreach (string item in items) {
append_text(_(item));
}
changed.connect(() => parent.combo_edited(path, active));
}
}