[caribou: 11/15] Introduce scanner class.



commit c30152c8750ec7dd992ad99b3b7f0f12b7fc0c47
Author: Eitan Isaacson <eitan monotonous org>
Date:   Sat May 28 13:10:22 2011 -0700

    Introduce scanner class.

 libcaribou/Makefile.am  |    1 +
 libcaribou/scanner.vala |  241 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 242 insertions(+), 0 deletions(-)
---
diff --git a/libcaribou/Makefile.am b/libcaribou/Makefile.am
index 50c51f5..65a4ca5 100644
--- a/libcaribou/Makefile.am
+++ b/libcaribou/Makefile.am
@@ -38,6 +38,7 @@ libcaribou_la_SOURCES = \
 	row-model.vala \
 	key-model.vala \
 	column-model.vala \
+	scanner.vala \
 	util.vala \
 	json-deserializer.vala \
 	iscannable-item.vala \
diff --git a/libcaribou/scanner.vala b/libcaribou/scanner.vala
new file mode 100644
index 0000000..08321bd
--- /dev/null
+++ b/libcaribou/scanner.vala
@@ -0,0 +1,241 @@
+namespace Caribou {
+    public class Scanner : Object {
+        public bool bind_settings { get; construct; default=true; }
+
+        private ScanGrouping _scan_grouping;
+        public int scan_grouping {
+            get {
+                return (int) _scan_grouping;
+            }
+
+            set construct {
+                _scan_grouping = (ScanGrouping) value;
+                if (root_group != null)
+                    root_group.scan_grouping = _scan_grouping;
+                reset ();
+            }
+        }
+
+        private bool _scan_enabled;
+        public bool scan_enabled {
+            get { return _scan_enabled; }
+            set construct {
+                _scan_enabled = value;
+                if (_scan_enabled)
+                    enable ();
+                else
+                    disable ();
+            }
+        }
+        
+        private double _step_time;
+        public double step_time {
+            get { return _step_time; }
+            set construct {
+                _step_time = value;
+                if (scan_tid != 0) {
+                    GLib.Source.remove (scan_tid);
+                    scan_tid = GLib.Timeout.add ((int) (_step_time*1000), scan);
+                }
+            }
+        }
+
+        private string _switch_device;
+        public string switch_device {
+            get { return _switch_device; }
+            set construct {
+                _switch_device = value;
+                configure_switch ();
+            }
+        }
+
+        private string _keyboard_key;
+        public string keyboard_key {
+            get { return _keyboard_key; }
+            set construct {
+                _keyboard_key = value;
+                configure_switch ();
+            }
+        }
+
+        private int _mouse_button;
+        public int mouse_button {
+            get { return _mouse_button; }
+            set construct {
+                _mouse_button = value;
+                configure_switch ();
+            }
+        }
+
+        public int scan_cycles { get; set construct; default=1; }
+        public bool autorestart { get; set construct; default=false; }
+        public bool inverse_scanning { get; set construct; default=false; }
+
+        private delegate void UnconfigureSwitchFunc();
+        private UnconfigureSwitchFunc unconfigure_switch_func;
+
+        private uint scan_tid;
+        private KeyboardModel keyboard;
+        private IScannableGroup root_group;
+        private Settings caribou_settings;
+        private bool started;
+
+        construct {
+            /* defaults */
+            _scan_grouping = ScanGrouping.SUBGROUPS;
+            _step_time = 1.0;
+            _switch_device = "keyboard";
+
+            if (bind_settings)
+                do_bind_settings ();
+        }
+
+        private void do_bind_settings () {
+            caribou_settings = new Settings ("org.gnome.caribou");
+            string[] settings = {"scan-grouping", "step-time", "scan-cycles",
+                                 "autorestart", "inverse-scanning", "switch-device",
+                                 "keyboard-key", "mouse-button", "scan-enabled"};
+
+            foreach (string setting in settings) {
+                caribou_settings.bind (setting, this, setting, SettingsBindFlags.GET);
+            }
+        }
+
+        private bool select () {
+            IScannableItem? item = root_group.child_select ();
+
+            if (item is IScannableGroup) {
+                step ();
+                return true;
+            } else {
+                reset ();
+                return false;
+            }
+        }
+
+        private void switch_pressed (uint code, bool pressed) {
+            if (pressed) {
+                if (!started) {
+                    step ();
+                    start ();
+                    return;
+                }
+
+                stop ();
+
+                if (inverse_scanning) {
+                    step ();
+                    start ();
+                } else {
+                    if (select () || autorestart)
+                        start ();
+                }
+            }
+        }
+
+        public void set_keyboard (KeyboardModel keyboard) {
+            GroupModel group = keyboard.get_group(keyboard.active_group);
+            this.keyboard = keyboard;
+            this.keyboard.notify["active-group"].connect(on_group_changed);
+            set_active_level (group.get_level (group.active_level));
+
+            foreach (string group_name in keyboard.get_groups()) {
+                group = keyboard.get_group(group_name);
+                group.notify["active-level"].connect(on_level_changed);
+            }
+        }
+
+        private void on_level_changed (Object obj, ParamSpec prop) {
+            GroupModel group = (GroupModel) obj;
+            set_active_level (group.get_level (group.active_level));
+        }
+
+        private void on_group_changed (Object obj, ParamSpec prop) {
+            GroupModel group = keyboard.get_group(keyboard.active_group);
+            set_active_level (group.get_level (group.active_level));
+        }
+
+        private void set_active_level (LevelModel level) {
+            root_group = (IScannableGroup) level;
+            root_group.scan_grouping = _scan_grouping;
+        }
+
+        public void reset () {
+            if (root_group != null)
+                root_group.scan_reset ();
+        }
+
+        private void enable () {
+            configure_switch ();
+        }
+
+        private void disable () {
+            unconfigure_switch ();
+        }
+
+        private void start () {
+            if (started || root_group == null)
+                return;
+
+            started = true;
+
+            scan_tid = GLib.Timeout.add((int) (_step_time*1000), scan);
+        }
+
+        private void stop () {
+            if (!started)
+                return;
+
+            started = false;
+            if (scan_tid != 0)
+                GLib.Source.remove (scan_tid);
+            scan_tid = 0;
+        }
+
+        private IScannableItem? step () {
+            IScannableItem item = root_group.child_step (scan_cycles);            
+
+            if (item == null) {
+                reset ();
+            }
+
+            return item;
+        }
+
+        private bool scan () {
+            if (inverse_scanning)
+                select ();
+            else
+                return (step () != null);
+
+            return true;
+        }
+
+        private void unconfigure_switch () {
+            if (unconfigure_switch_func != null)
+                unconfigure_switch_func ();
+            unconfigure_switch_func = null;
+        }
+
+        private void configure_switch () {
+            if (!scan_enabled)
+                return;
+            
+            unconfigure_switch ();
+
+            XAdapter xadapter = XAdapter.get_default();
+            if (switch_device == "keyboard" && keyboard_key != null) {
+                uint keyval = Gdk.keyval_from_name (keyboard_key);
+                xadapter.register_key_func (keyval, switch_pressed);
+                unconfigure_switch_func = () => {
+                    xadapter.register_key_func (keyval, null);
+                };
+            } else if (switch_device == "mouse" && mouse_button != 0) {
+                xadapter.register_button_func (mouse_button, switch_pressed);
+                unconfigure_switch_func = () => {
+                    xadapter.register_key_func (mouse_button, null);
+                };
+            }
+        }
+    }
+}
\ No newline at end of file



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]