don't show rectangle when it's too small

This commit is contained in:
Michael Zhang 2021-01-06 13:30:23 -06:00
parent 1edac3a62a
commit 8d863206b3
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B

View file

@ -158,7 +158,11 @@ impl Gui {
} }
impl State { impl State {
pub fn rect(&self) -> Rectangle { pub fn rect(&self) -> Option<Rectangle> {
if self.dx < 0 || self.dy < 0 {
return None;
}
let tlx = self.dx.min(self.mx); let tlx = self.dx.min(self.mx);
let tly = self.dy.min(self.my); let tly = self.dy.min(self.my);
@ -168,41 +172,48 @@ impl Gui {
let rw = (brx - tlx) as u16; let rw = (brx - tlx) as u16;
let rh = (bry - tly) as u16; let rh = (bry - tly) as u16;
Rectangle::new(tlx, tly, rw, rh) if rw <= 2 || rh <= 2 {
return None;
}
Some(Rectangle::new(tlx, tly, rw, rh))
} }
} }
let mut state = State::default(); let mut state = State::default();
state.dx = -1;
state.dy = -1;
let mut cancelled = false; let mut cancelled = false;
let redraw = |state: &State| -> Result<()> { let redraw = |state: &State| -> Result<()> {
xcb_image::put(&self.conn, window_id, window_gc, &image.image, 0, 0); xcb_image::put(&self.conn, window_id, window_gc, &image.image, 0, 0);
if state.dragging { if let Some(rect) = state.rect() {
let rect = state.rect(); if state.dragging {
xproto::change_gc( xproto::change_gc(
&self.conn, &self.conn,
window_gc, window_gc,
&[(xcb::GC_FOREGROUND, screen.black_pixel())], &[(xcb::GC_FOREGROUND, screen.black_pixel())],
); );
xproto::poly_rectangle(&self.conn, window_id, window_gc, &[rect]); xproto::poly_rectangle(&self.conn, window_id, window_gc, &[rect]);
let rect2 = Rectangle::new( let rect2 = Rectangle::new(
rect.x() + 1, rect.x() + 1,
rect.y() + 1, rect.y() + 1,
rect.width() - 2, rect.width() - 2,
rect.height() - 2, rect.height() - 2,
); );
xproto::change_gc( xproto::change_gc(
&self.conn, &self.conn,
window_gc, window_gc,
&[(xcb::GC_FOREGROUND, screen.white_pixel())], &[(xcb::GC_FOREGROUND, screen.white_pixel())],
); );
xproto::poly_rectangle(&self.conn, window_id, window_gc, &[rect2]); xproto::poly_rectangle(&self.conn, window_id, window_gc, &[rect2]);
}
} }
self.conn.flush(); self.conn.flush();
Ok(()) Ok(())
}; };
@ -227,6 +238,8 @@ impl Gui {
xcb::BUTTON_PRESS => { xcb::BUTTON_PRESS => {
let button_evt = unsafe { xcb::cast_event::<xcb::ButtonPressEvent>(&evt) }; let button_evt = unsafe { xcb::cast_event::<xcb::ButtonPressEvent>(&evt) };
info!("pressed mouse button {:?}", button_evt.detail()); info!("pressed mouse button {:?}", button_evt.detail());
state.mx = button_evt.root_x();
state.my = button_evt.root_y();
state.dx = button_evt.root_x(); state.dx = button_evt.root_x();
state.dy = button_evt.root_y(); state.dy = button_evt.root_y();
@ -241,7 +254,10 @@ impl Gui {
// left mouse button // left mouse button
if state.dragging && button_evt.detail() == 1 { if state.dragging && button_evt.detail() == 1 {
break; state.dragging = false;
if let Some(_) = state.rect() {
break;
}
} }
} }
xcb::MOTION_NOTIFY => { xcb::MOTION_NOTIFY => {
@ -250,7 +266,7 @@ impl Gui {
state.my = motion_evt.root_y(); state.my = motion_evt.root_y();
} }
v => { v => {
println!("event type: {:?}", v); info!("event type: {:?}", v);
} }
} }
@ -261,7 +277,7 @@ impl Gui {
xproto::ungrab_keyboard(&self.conn, xcb::CURRENT_TIME).request_check()?; xproto::ungrab_keyboard(&self.conn, xcb::CURRENT_TIME).request_check()?;
xproto::ungrab_pointer(&self.conn, xcb::CURRENT_TIME).request_check()?; xproto::ungrab_pointer(&self.conn, xcb::CURRENT_TIME).request_check()?;
Ok(if cancelled { None } else { Some(state.rect()) }) Ok(if cancelled { None } else { state.rect() })
} }
} }