Mercurial > tablet-emu
comparison 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 |
comparison
equal
deleted
inserted
replaced
2:39f87ef69b2a | 3:72e63d6a3f8a |
---|---|
189 | 189 |
190 fn input_synchronize_new(code: SynchronizeKind, value: i32) -> input_event { | 190 fn input_synchronize_new(code: SynchronizeKind, value: i32) -> input_event { |
191 input_event_new(EventKind::Synchronize, code as u16, value) | 191 input_event_new(EventKind::Synchronize, code as u16, value) |
192 } | 192 } |
193 | 193 |
194 struct State { | |
195 dev: UInputHandle<File>, | |
196 width: f64, | |
197 height: f64, | |
198 selected_tool: Key, | |
199 pressed: bool, | |
200 } | |
201 | |
194 fn build_ui(application: >k::Application) { | 202 fn build_ui(application: >k::Application) { |
195 let dev = match create_uinput_device() { | 203 let dev = match create_uinput_device() { |
196 Ok(dev) => Arc::new(dev), | 204 Ok(dev) => dev, |
197 Err(err) => { | 205 Err(err) => { |
198 match err.kind() { | 206 match err.kind() { |
199 ErrorKind::NotFound => { | 207 ErrorKind::NotFound => { |
200 eprintln!("Couldn’t find /dev/uinput: {}", err); | 208 eprintln!("Couldn’t find /dev/uinput: {}", err); |
201 eprintln!("Maybe you forgot to `modprobe uinput`?"); | 209 eprintln!("Maybe you forgot to `modprobe uinput`?"); |
213 "New device at {:?} ({:?})", | 221 "New device at {:?} ({:?})", |
214 dev.evdev_path().unwrap(), | 222 dev.evdev_path().unwrap(), |
215 dev.sys_path().unwrap() | 223 dev.sys_path().unwrap() |
216 ); | 224 ); |
217 | 225 |
226 let state = Arc::new(Mutex::new(State { | |
227 dev, | |
228 width: WIDTH as f64, | |
229 height: HEIGHT as f64, | |
230 selected_tool: Key::ButtonToolPen, | |
231 pressed: false, | |
232 })); | |
233 | |
218 let window = gtk::ApplicationWindow::new(application); | 234 let window = gtk::ApplicationWindow::new(application); |
219 | 235 |
220 window.set_title("tablet-emu"); | 236 window.set_title("tablet-emu"); |
221 window.set_position(gtk::WindowPosition::Center); | 237 window.set_position(gtk::WindowPosition::Center); |
222 | 238 |
223 let hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0); | 239 let hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0); |
224 let tools_box = gtk::Box::new(gtk::Orientation::Vertical, 0); | 240 let tools_box = gtk::Box::new(gtk::Orientation::Vertical, 0); |
225 | 241 |
226 let current_tool = Arc::new(Mutex::new(Key::ButtonToolPen)); | |
227 let tool1 = gtk::Button::with_label("Pen"); | 242 let tool1 = gtk::Button::with_label("Pen"); |
228 let tool2 = gtk::Button::with_label("Rubber"); | 243 let tool2 = gtk::Button::with_label("Rubber"); |
229 let tool3 = gtk::Button::with_label("Brush"); | 244 let tool3 = gtk::Button::with_label("Brush"); |
230 let tool4 = gtk::Button::with_label("Pencil"); | 245 let tool4 = gtk::Button::with_label("Pencil"); |
231 let tool5 = gtk::Button::with_label("Airbrush"); | 246 let tool5 = gtk::Button::with_label("Airbrush"); |
232 | 247 |
233 macro_rules! impl_tool_signal { | 248 macro_rules! impl_tool_signal { |
234 ($tool:ident) => { | 249 ($tool:ident) => { |
235 let current_tool_weak = Arc::downgrade(¤t_tool); | 250 let state_weak = Arc::downgrade(&state); |
236 $tool.connect_clicked(move |b| { | 251 $tool.connect_clicked(move |b| { |
237 let current_tool = current_tool_weak.upgrade().unwrap(); | 252 let state = state_weak.upgrade().unwrap(); |
238 let mut current_tool = current_tool.lock().unwrap(); | 253 let mut state = state.lock().unwrap(); |
239 *current_tool = match b.get_label().unwrap().as_str() { | 254 state.selected_tool = match b.get_label().unwrap().as_str() { |
240 "Pen" => Key::ButtonToolPen, | 255 "Pen" => Key::ButtonToolPen, |
241 "Rubber" => Key::ButtonToolRubber, | 256 "Rubber" => Key::ButtonToolRubber, |
242 "Brush" => Key::ButtonToolBrush, | 257 "Brush" => Key::ButtonToolBrush, |
243 "Pencil" => Key::ButtonToolPencil, | 258 "Pencil" => Key::ButtonToolPencil, |
244 "Airbrush" => Key::ButtonToolAirbrush, | 259 "Airbrush" => Key::ButtonToolAirbrush, |
257 tools_box.add(&tool2); | 272 tools_box.add(&tool2); |
258 tools_box.add(&tool3); | 273 tools_box.add(&tool3); |
259 tools_box.add(&tool4); | 274 tools_box.add(&tool4); |
260 tools_box.add(&tool5); | 275 tools_box.add(&tool5); |
261 | 276 |
262 let current_size = Arc::new(Mutex::new((WIDTH as f64, HEIGHT as f64))); | |
263 let pressed = Arc::new(Mutex::new(false)); | |
264 | |
265 let drawing_area = gtk::DrawingArea::new(); | 277 let drawing_area = gtk::DrawingArea::new(); |
266 drawing_area.set_size_request(WIDTH, HEIGHT); | 278 drawing_area.set_size_request(WIDTH, HEIGHT); |
267 drawing_area.set_hexpand(true); | 279 drawing_area.set_hexpand(true); |
268 drawing_area.set_events( | 280 drawing_area.set_events( |
269 gdk::EventMask::BUTTON_PRESS_MASK | 281 gdk::EventMask::BUTTON_PRESS_MASK |
270 | gdk::EventMask::BUTTON_RELEASE_MASK | 282 | gdk::EventMask::BUTTON_RELEASE_MASK |
271 | gdk::EventMask::POINTER_MOTION_MASK, | 283 | gdk::EventMask::POINTER_MOTION_MASK, |
272 ); | 284 ); |
273 let current_size_weak = Arc::downgrade(¤t_size); | 285 let state_weak = Arc::downgrade(&state); |
274 drawing_area.connect_configure_event(move |_, event| { | 286 drawing_area.connect_configure_event(move |_, event| { |
275 let current_size = current_size_weak.upgrade().unwrap(); | 287 let state = state_weak.upgrade().unwrap(); |
276 let mut current_size = current_size.lock().unwrap(); | 288 let mut state = state.lock().unwrap(); |
277 *current_size = match event.get_size() { | 289 match event.get_size() { |
278 (width, height) => (width as f64, height as f64), | 290 (width, height) => { |
279 }; | 291 state.width = width as f64; |
292 state.height = height as f64; | |
293 } | |
294 } | |
280 true | 295 true |
281 }); | 296 }); |
282 let dev_weak = Arc::downgrade(&dev); | 297 let state_weak = Arc::downgrade(&state); |
283 let current_size_weak = Arc::downgrade(¤t_size); | |
284 let current_tool_weak = Arc::downgrade(¤t_tool); | |
285 let pressed_weak = Arc::downgrade(&pressed); | |
286 drawing_area.connect_button_press_event(move |_, event| { | 298 drawing_area.connect_button_press_event(move |_, event| { |
287 if event.get_button() != 1 { | 299 if event.get_button() != 1 { |
288 return Inhibit(false); | 300 return Inhibit(false); |
289 } | 301 } |
290 | 302 |
291 let dev = dev_weak.upgrade().unwrap(); | 303 let state = state_weak.upgrade().unwrap(); |
292 let current_tool = current_tool_weak.upgrade().unwrap(); | 304 let mut state = state.lock().unwrap(); |
293 let pressed = pressed_weak.upgrade().unwrap(); | 305 state.pressed = true; |
294 let mut pressed = pressed.lock().unwrap(); | |
295 *pressed = true; | |
296 let (x, y) = event.get_position(); | 306 let (x, y) = event.get_position(); |
297 //println!("press tool {} at {}, {}", current_tool.lock().unwrap(), x, y); | 307 //println!("press tool {} at {}, {}", current_tool.lock().unwrap(), x, y); |
298 let current_size = current_size_weak.upgrade().unwrap(); | 308 state.dev.write(&[ |
299 let current_size = current_size.lock().unwrap(); | 309 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32), |
300 let (width, height) = *current_size; | 310 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32), |
301 dev.write(&[ | |
302 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / width) as i32), | |
303 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / height) as i32), | |
304 input_axis_new(AbsoluteAxis::Z, 0), | 311 input_axis_new(AbsoluteAxis::Z, 0), |
305 input_axis_new(AbsoluteAxis::Wheel, 0), | 312 input_axis_new(AbsoluteAxis::Wheel, 0), |
306 input_axis_new(AbsoluteAxis::Pressure, 1024), | 313 input_axis_new(AbsoluteAxis::Pressure, 1024), |
307 input_axis_new(AbsoluteAxis::Distance, 0), | 314 input_axis_new(AbsoluteAxis::Distance, 0), |
308 input_axis_new(AbsoluteAxis::TiltX, 16), | 315 input_axis_new(AbsoluteAxis::TiltX, 16), |
309 input_axis_new(AbsoluteAxis::TiltY, 0), | 316 input_axis_new(AbsoluteAxis::TiltY, 0), |
310 input_misc_new(MiscKind::Serial, 0), | 317 input_misc_new(MiscKind::Serial, 0), |
311 input_key_new(*current_tool.lock().unwrap(), 0), | 318 input_key_new(state.selected_tool, 1), |
312 input_synchronize_new(SynchronizeKind::Report, 0), | 319 input_synchronize_new(SynchronizeKind::Report, 0), |
313 ]) | 320 ]) |
314 .unwrap(); | 321 .unwrap(); |
315 Inhibit(false) | 322 Inhibit(false) |
316 }); | 323 }); |
317 let dev_weak = Arc::downgrade(&dev); | 324 let state_weak = Arc::downgrade(&state); |
318 let current_size_weak = Arc::downgrade(¤t_size); | |
319 let current_tool_weak = Arc::downgrade(¤t_tool); | |
320 let pressed_weak = Arc::downgrade(&pressed); | |
321 drawing_area.connect_button_release_event(move |_, event| { | 325 drawing_area.connect_button_release_event(move |_, event| { |
322 if event.get_button() != 1 { | 326 if event.get_button() != 1 { |
323 return Inhibit(false); | 327 return Inhibit(false); |
324 } | 328 } |
325 | 329 |
326 let dev = dev_weak.upgrade().unwrap(); | 330 let state = state_weak.upgrade().unwrap(); |
327 let current_tool = current_tool_weak.upgrade().unwrap(); | 331 let mut state = state.lock().unwrap(); |
328 let (x, y) = event.get_position(); | 332 let (x, y) = event.get_position(); |
329 let pressed = pressed_weak.upgrade().unwrap(); | 333 state.pressed = false; |
330 let mut pressed = pressed.lock().unwrap(); | |
331 *pressed = false; | |
332 //println!("release {}, {}", x, y); | 334 //println!("release {}, {}", x, y); |
333 let current_size = current_size_weak.upgrade().unwrap(); | 335 state.dev.write(&[ |
334 let current_size = current_size.lock().unwrap(); | 336 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32), |
335 let (width, height) = *current_size; | 337 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32), |
336 dev.write(&[ | |
337 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / width) as i32), | |
338 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / height) as i32), | |
339 input_axis_new(AbsoluteAxis::Z, 0), | 338 input_axis_new(AbsoluteAxis::Z, 0), |
340 input_axis_new(AbsoluteAxis::Wheel, 0), | 339 input_axis_new(AbsoluteAxis::Wheel, 0), |
341 input_axis_new(AbsoluteAxis::Pressure, 0), | 340 input_axis_new(AbsoluteAxis::Pressure, 0), |
342 input_axis_new(AbsoluteAxis::Distance, 16), | 341 input_axis_new(AbsoluteAxis::Distance, 16), |
343 input_axis_new(AbsoluteAxis::TiltX, 16), | 342 input_axis_new(AbsoluteAxis::TiltX, 16), |
344 input_axis_new(AbsoluteAxis::TiltY, 0), | 343 input_axis_new(AbsoluteAxis::TiltY, 0), |
345 input_misc_new(MiscKind::Serial, 0), | 344 input_misc_new(MiscKind::Serial, 0), |
346 input_key_new(*current_tool.lock().unwrap(), 0), | 345 input_key_new(state.selected_tool, 1), |
347 input_synchronize_new(SynchronizeKind::Report, 0), | 346 input_synchronize_new(SynchronizeKind::Report, 0), |
348 ]) | 347 ]) |
349 .unwrap(); | 348 .unwrap(); |
350 Inhibit(false) | 349 Inhibit(false) |
351 }); | 350 }); |
352 drawing_area.connect_motion_notify_event(move |_, event| { | 351 drawing_area.connect_motion_notify_event(move |_, event| { |
352 let state = state.lock().unwrap(); | |
353 let (x, y) = event.get_position(); | 353 let (x, y) = event.get_position(); |
354 let pressed = pressed.lock().unwrap(); | |
355 //println!("motion {}, {}", x, y); | 354 //println!("motion {}, {}", x, y); |
356 let current_size = current_size.lock().unwrap(); | 355 state.dev.write(&[ |
357 let (width, height) = *current_size; | 356 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32), |
358 dev.write(&[ | 357 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32), |
359 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / width) as i32), | |
360 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / height) as i32), | |
361 input_axis_new(AbsoluteAxis::Z, 0), | 358 input_axis_new(AbsoluteAxis::Z, 0), |
362 input_axis_new(AbsoluteAxis::Wheel, 0), | 359 input_axis_new(AbsoluteAxis::Wheel, 0), |
363 input_axis_new(AbsoluteAxis::Pressure, if *pressed { 2048 } else { 0 }), | 360 input_axis_new(AbsoluteAxis::Pressure, if state.pressed { 2048 } else { 0 }), |
364 input_axis_new(AbsoluteAxis::Distance, if *pressed { 0 } else { 32 }), | 361 input_axis_new(AbsoluteAxis::Distance, if state.pressed { 0 } else { 32 }), |
365 input_axis_new(AbsoluteAxis::TiltX, 16), | 362 input_axis_new(AbsoluteAxis::TiltX, 16), |
366 input_axis_new(AbsoluteAxis::TiltY, 0), | 363 input_axis_new(AbsoluteAxis::TiltY, 0), |
367 input_misc_new(MiscKind::Serial, 0), | 364 input_misc_new(MiscKind::Serial, 0), |
368 input_key_new(*current_tool.lock().unwrap(), 0), | 365 input_key_new(state.selected_tool, 1), |
369 input_synchronize_new(SynchronizeKind::Report, 0), | 366 input_synchronize_new(SynchronizeKind::Report, 0), |
370 ]) | 367 ]) |
371 .unwrap(); | 368 .unwrap(); |
372 Inhibit(false) | 369 Inhibit(false) |
373 }); | 370 }); |