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: &gtk::Application) { 202 fn build_ui(application: &gtk::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(&current_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(&current_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(&current_size);
284 let current_tool_weak = Arc::downgrade(&current_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(&current_size);
319 let current_tool_weak = Arc::downgrade(&current_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 });