diff src/main.rs @ 3:72e63d6a3f8a

Simplify state handling into a single struct.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 09 Oct 2020 15:03:55 +0200
parents 39f87ef69b2a
children 2e074d185151
line wrap: on
line diff
--- a/src/main.rs
+++ b/src/main.rs
@@ -191,9 +191,17 @@ fn input_synchronize_new(code: Synchroni
     input_event_new(EventKind::Synchronize, code as u16, value)
 }
 
+struct State {
+    dev: UInputHandle<File>,
+    width: f64,
+    height: f64,
+    selected_tool: Key,
+    pressed: bool,
+}
+
 fn build_ui(application: &gtk::Application) {
     let dev = match create_uinput_device() {
-        Ok(dev) => Arc::new(dev),
+        Ok(dev) => dev,
         Err(err) => {
             match err.kind() {
                 ErrorKind::NotFound => {
@@ -215,6 +223,14 @@ fn build_ui(application: &gtk::Applicati
         dev.sys_path().unwrap()
     );
 
+    let state = Arc::new(Mutex::new(State {
+        dev,
+        width: WIDTH as f64,
+        height: HEIGHT as f64,
+        selected_tool: Key::ButtonToolPen,
+        pressed: false,
+    }));
+
     let window = gtk::ApplicationWindow::new(application);
 
     window.set_title("tablet-emu");
@@ -223,7 +239,6 @@ fn build_ui(application: &gtk::Applicati
     let hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0);
     let tools_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
 
-    let current_tool = Arc::new(Mutex::new(Key::ButtonToolPen));
     let tool1 = gtk::Button::with_label("Pen");
     let tool2 = gtk::Button::with_label("Rubber");
     let tool3 = gtk::Button::with_label("Brush");
@@ -232,11 +247,11 @@ fn build_ui(application: &gtk::Applicati
 
     macro_rules! impl_tool_signal {
         ($tool:ident) => {
-            let current_tool_weak = Arc::downgrade(&current_tool);
+            let state_weak = Arc::downgrade(&state);
             $tool.connect_clicked(move |b| {
-                let current_tool = current_tool_weak.upgrade().unwrap();
-                let mut current_tool = current_tool.lock().unwrap();
-                *current_tool = match b.get_label().unwrap().as_str() {
+                let state = state_weak.upgrade().unwrap();
+                let mut state = state.lock().unwrap();
+                state.selected_tool = match b.get_label().unwrap().as_str() {
                     "Pen" => Key::ButtonToolPen,
                     "Rubber" => Key::ButtonToolRubber,
                     "Brush" => Key::ButtonToolBrush,
@@ -259,9 +274,6 @@ fn build_ui(application: &gtk::Applicati
     tools_box.add(&tool4);
     tools_box.add(&tool5);
 
-    let current_size = Arc::new(Mutex::new((WIDTH as f64, HEIGHT as f64)));
-    let pressed = Arc::new(Mutex::new(false));
-
     let drawing_area = gtk::DrawingArea::new();
     drawing_area.set_size_request(WIDTH, HEIGHT);
     drawing_area.set_hexpand(true);
@@ -270,37 +282,32 @@ fn build_ui(application: &gtk::Applicati
             | gdk::EventMask::BUTTON_RELEASE_MASK
             | gdk::EventMask::POINTER_MOTION_MASK,
     );
-    let current_size_weak = Arc::downgrade(&current_size);
+    let state_weak = Arc::downgrade(&state);
     drawing_area.connect_configure_event(move |_, event| {
-        let current_size = current_size_weak.upgrade().unwrap();
-        let mut current_size = current_size.lock().unwrap();
-        *current_size = match event.get_size() {
-            (width, height) => (width as f64, height as f64),
-        };
+        let state = state_weak.upgrade().unwrap();
+        let mut state = state.lock().unwrap();
+        match event.get_size() {
+            (width, height) => {
+                state.width = width as f64;
+                state.height = height as f64;
+            }
+        }
         true
     });
-    let dev_weak = Arc::downgrade(&dev);
-    let current_size_weak = Arc::downgrade(&current_size);
-    let current_tool_weak = Arc::downgrade(&current_tool);
-    let pressed_weak = Arc::downgrade(&pressed);
+    let state_weak = Arc::downgrade(&state);
     drawing_area.connect_button_press_event(move |_, event| {
         if event.get_button() != 1 {
             return Inhibit(false);
         }
 
-        let dev = dev_weak.upgrade().unwrap();
-        let current_tool = current_tool_weak.upgrade().unwrap();
-        let pressed = pressed_weak.upgrade().unwrap();
-        let mut pressed = pressed.lock().unwrap();
-        *pressed = true;
+        let state = state_weak.upgrade().unwrap();
+        let mut state = state.lock().unwrap();
+        state.pressed = true;
         let (x, y) = event.get_position();
         //println!("press tool {} at {}, {}", current_tool.lock().unwrap(), x, y);
-        let current_size = current_size_weak.upgrade().unwrap();
-        let current_size = current_size.lock().unwrap();
-        let (width, height) = *current_size;
-        dev.write(&[
-            input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / width) as i32),
-            input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / height) as i32),
+        state.dev.write(&[
+            input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32),
+            input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32),
             input_axis_new(AbsoluteAxis::Z, 0),
             input_axis_new(AbsoluteAxis::Wheel, 0),
             input_axis_new(AbsoluteAxis::Pressure, 1024),
@@ -308,34 +315,26 @@ fn build_ui(application: &gtk::Applicati
             input_axis_new(AbsoluteAxis::TiltX, 16),
             input_axis_new(AbsoluteAxis::TiltY, 0),
             input_misc_new(MiscKind::Serial, 0),
-            input_key_new(*current_tool.lock().unwrap(), 0),
+            input_key_new(state.selected_tool, 1),
             input_synchronize_new(SynchronizeKind::Report, 0),
         ])
         .unwrap();
         Inhibit(false)
     });
-    let dev_weak = Arc::downgrade(&dev);
-    let current_size_weak = Arc::downgrade(&current_size);
-    let current_tool_weak = Arc::downgrade(&current_tool);
-    let pressed_weak = Arc::downgrade(&pressed);
+    let state_weak = Arc::downgrade(&state);
     drawing_area.connect_button_release_event(move |_, event| {
         if event.get_button() != 1 {
             return Inhibit(false);
         }
 
-        let dev = dev_weak.upgrade().unwrap();
-        let current_tool = current_tool_weak.upgrade().unwrap();
+        let state = state_weak.upgrade().unwrap();
+        let mut state = state.lock().unwrap();
         let (x, y) = event.get_position();
-        let pressed = pressed_weak.upgrade().unwrap();
-        let mut pressed = pressed.lock().unwrap();
-        *pressed = false;
+        state.pressed = false;
         //println!("release {}, {}", x, y);
-        let current_size = current_size_weak.upgrade().unwrap();
-        let current_size = current_size.lock().unwrap();
-        let (width, height) = *current_size;
-        dev.write(&[
-            input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / width) as i32),
-            input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / height) as i32),
+        state.dev.write(&[
+            input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32),
+            input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32),
             input_axis_new(AbsoluteAxis::Z, 0),
             input_axis_new(AbsoluteAxis::Wheel, 0),
             input_axis_new(AbsoluteAxis::Pressure, 0),
@@ -343,29 +342,27 @@ fn build_ui(application: &gtk::Applicati
             input_axis_new(AbsoluteAxis::TiltX, 16),
             input_axis_new(AbsoluteAxis::TiltY, 0),
             input_misc_new(MiscKind::Serial, 0),
-            input_key_new(*current_tool.lock().unwrap(), 0),
+            input_key_new(state.selected_tool, 1),
             input_synchronize_new(SynchronizeKind::Report, 0),
         ])
         .unwrap();
         Inhibit(false)
     });
     drawing_area.connect_motion_notify_event(move |_, event| {
+        let state = state.lock().unwrap();
         let (x, y) = event.get_position();
-        let pressed = pressed.lock().unwrap();
         //println!("motion {}, {}", x, y);
-        let current_size = current_size.lock().unwrap();
-        let (width, height) = *current_size;
-        dev.write(&[
-            input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / width) as i32),
-            input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / height) as i32),
+        state.dev.write(&[
+            input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32),
+            input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32),
             input_axis_new(AbsoluteAxis::Z, 0),
             input_axis_new(AbsoluteAxis::Wheel, 0),
-            input_axis_new(AbsoluteAxis::Pressure, if *pressed { 2048 } else { 0 }),
-            input_axis_new(AbsoluteAxis::Distance, if *pressed { 0 } else { 32 }),
+            input_axis_new(AbsoluteAxis::Pressure, if state.pressed { 2048 } else { 0 }),
+            input_axis_new(AbsoluteAxis::Distance, if state.pressed { 0 } else { 32 }),
             input_axis_new(AbsoluteAxis::TiltX, 16),
             input_axis_new(AbsoluteAxis::TiltY, 0),
             input_misc_new(MiscKind::Serial, 0),
-            input_key_new(*current_tool.lock().unwrap(), 0),
+            input_key_new(state.selected_tool, 1),
             input_synchronize_new(SynchronizeKind::Report, 0),
         ])
         .unwrap();