summaryrefslogtreecommitdiff
path: root/libcaribou/key-model.vala
blob: 7153bc6c6266e18d629caf324479b17bf6b4ce02 (plain)
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
using GLib;

namespace Caribou {
    public class KeyModel : GLib.Object, IScannableItem, IKeyboardObject {
        public string align { get; set; default = "center"; }
        public double width { get; set; default = 1.0; }
        public string toggle { get; set; default = ""; }

        public bool show_subkeys { get; private set; default = false; }
        public string name { get; private set; }
        public uint keyval { get; private set; }

        public bool scan_stepping { get; internal set; }
        private bool _scan_selected;
        public bool scan_selected {
            get {
                return _scan_selected;
            }

            internal set {
                _scan_selected = value;
                if (_scan_selected)
                    activate ();
            }
        }

        private uint hold_tid;
        private XAdapter xadapter;
        private Gee.ArrayList<KeyModel> extended_keys;

        public signal void key_pressed ();
        public signal void key_released ();
        public signal void key_hold_end ();
        public signal void key_hold ();

        public KeyModel (string name) {
            this.name = name;
            xadapter = XAdapter.get_default();
            keyval = Gdk.keyval_from_name (name);
            extended_keys = new Gee.ArrayList<KeyModel> ();
        }

        internal void add_subkey (KeyModel key) {
            key.key_activated.connect(on_subkey_activated);
            extended_keys.add (key);
        }

        private void on_subkey_activated (KeyModel key) {
            key_activated (key);
            show_subkeys = false;
        }

        public void press () {
            hold_tid = GLib.Timeout.add(1000, on_key_held);
            key_pressed();
        }

        public void release () {
            key_released();
            if (hold_tid != 0) {
                GLib.Source.remove (hold_tid);
                hold_tid = 0;
                key_activated (this);
                if (keyval != 0) {
                    xadapter.keyval_press(keyval);
                    xadapter.keyval_release(keyval);
                }
            } else {
                key_hold_end ();
            }
        }

        private bool on_key_held () {
            hold_tid = 0;
            if (extended_keys.size != 0)
                show_subkeys = true;
            key_hold ();
            return false;
        }

        public KeyModel[] get_extended_keys () {
            return (KeyModel[]) extended_keys.to_array ();
        }

        public KeyModel[] get_keys () {
            Gee.ArrayList<KeyModel> all_keys = new Gee.ArrayList<KeyModel> ();
            all_keys.add (this);
            all_keys.add_all (extended_keys);
            return (KeyModel[]) all_keys.to_array ();
        }

        public IKeyboardObject[] get_children () {
            return (IKeyboardObject[]) extended_keys.to_array ();
        }

        public void activate () {
            press ();
            GLib.Timeout.add(200, () => { release (); return false; });
        }
    }
}