diff options
-rw-r--r-- | src/app.rs | 86 |
1 files changed, 55 insertions, 31 deletions
@@ -11,6 +11,7 @@ use crate::{ | |||
11 | symmetry::Symmetry, | 11 | symmetry::Symmetry, |
12 | undo::{ModifyRecord, OpKind, PaintRecord, UndoStack}, | 12 | undo::{ModifyRecord, OpKind, PaintRecord, UndoStack}, |
13 | utils::{draw_text, handle_error, is_copy_event, is_paste_event, load_script}, | 13 | utils::{draw_text, handle_error, is_copy_event, is_paste_event, load_script}, |
14 | widget::{Container, HorAlign, Offset, Size, VertAlign}, | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | use std::{ | 17 | use std::{ |
@@ -326,48 +327,71 @@ impl<'ctx> AppState<'ctx> { | |||
326 | } | 327 | } |
327 | 328 | ||
328 | fn draw_statusline(&mut self) { | 329 | fn draw_statusline(&mut self) { |
329 | let (winsize_x, winsize_y) = self.canvas.window().size(); | 330 | let container = Container::new(Offset::Left(0), Offset::Bottom(40), &self.canvas) |
330 | let status_height: u32 = 20; | 331 | .width(Size::Max, &self.canvas) |
331 | let status_width = winsize_x; | 332 | .height(Size::Absolute(20), &self.canvas); |
332 | self.canvas.set_draw_color(WHITE); | 333 | self.canvas.set_draw_color(WHITE); |
333 | self.canvas | 334 | self.canvas.fill_rect(container.area()).unwrap(); |
334 | .fill_rect(rect!( | 335 | |
335 | 0, | 336 | let mut padding_box = Container::uninit() |
336 | winsize_y - status_height - 20, | 337 | .width(Size::Absolute(18), &self.canvas) |
337 | status_width, | 338 | .height(Size::Absolute(18), &self.canvas); |
338 | status_height | 339 | |
339 | )) | 340 | let mut primary = Container::uninit() |
340 | .unwrap(); | 341 | .width(Size::Absolute(16), &self.canvas) |
342 | .height(Size::Absolute(16), &self.canvas); | ||
343 | |||
344 | container.place(&mut padding_box, HorAlign::Right, VertAlign::Center); | ||
345 | padding_box.place(&mut primary, HorAlign::Center, VertAlign::Center); | ||
346 | |||
347 | self.canvas.set_draw_color(if !self.active_color { WHITE } else { BLACK }); | ||
348 | self.canvas.fill_rect(primary.area()).unwrap(); | ||
349 | self.canvas.set_draw_color(if self.active_color { WHITE } else { BLACK }); | ||
350 | |||
351 | let brush_box = (0..8) | ||
352 | .map(|x| (0..8).map(|y| (x, y).into()).collect::<Vec<MapPoint>>()) | ||
353 | .flatten() | ||
354 | .filter(|&pt| dither::bayer(self.dither_level, pt)) | ||
355 | .collect::<Vec<_>>(); | ||
356 | |||
357 | for pt in brush_box { | ||
358 | let canvas_pt = Point::from(primary.start) | ||
359 | + Point::from((pt.x as i32 * 2, pt.y as i32 * 2)); | ||
360 | self.canvas.fill_rect(rect!(canvas_pt.x(), canvas_pt.y(), 2, 2)).unwrap(); | ||
361 | } | ||
362 | |||
363 | // self.canvas | ||
364 | // .set_draw_color(if self.active_color { WHITE } else { BLACK }); | ||
365 | // self.canvas | ||
366 | // .fill_rect(Rect::from_center(primary.area().center(), 12, 12)) | ||
367 | // .unwrap(); | ||
368 | |||
341 | let mouse_coords = if let Some((x, y)) = self.idx_at_coord(self.mouse) { | 369 | let mouse_coords = if let Some((x, y)) = self.idx_at_coord(self.mouse) { |
342 | format!("{:3}, {:3}", x + 1, y + 1) | 370 | format!("{:3}, {:3}", x + 1, y + 1) |
343 | } else { | 371 | } else { |
344 | format!("---, ---") | 372 | format!("---, ---") |
345 | }; | 373 | }; |
346 | let status_text = format!( | 374 | let status_text = format!( |
347 | "[DITHER {}][SYM {}][PT {}][ACTIVE {}][KIND {}]", | 375 | "[DITHER {}][PT {}][KIND {}]", |
348 | self.dither_level, | 376 | self.dither_level, mouse_coords, self.brush |
349 | self.symmetry, | ||
350 | mouse_coords, | ||
351 | if self.active_color { "WHT" } else { "BLK" }, | ||
352 | self.brush | ||
353 | ); | 377 | ); |
354 | draw_text( | 378 | draw_text( |
355 | &mut self.canvas, | 379 | &mut self.canvas, |
356 | self.ttf_context, | 380 | self.ttf_context, |
357 | status_text, | 381 | status_text, |
358 | BLACK, | 382 | BLACK, |
359 | (0, winsize_y - status_height - 20), | 383 | container.start, |
360 | ); | 384 | ); |
361 | } | 385 | } |
362 | 386 | ||
363 | fn draw_command_box(&mut self) { | 387 | fn draw_command_box(&mut self) { |
364 | let (winsize_x, winsize_y) = self.canvas.window().size(); | 388 | let container = Container::new(Offset::Left(0), Offset::Bottom(20), &self.canvas) |
365 | let cmd_height: u32 = 20; | 389 | .width(Size::Max, &self.canvas) |
366 | let cmd_width = winsize_x; | 390 | .height(Size::Absolute(20), &self.canvas); |
391 | |||
367 | self.canvas.set_draw_color(BLACK); | 392 | self.canvas.set_draw_color(BLACK); |
368 | self.canvas | 393 | self.canvas.fill_rect(container.area()).unwrap(); |
369 | .fill_rect(rect!(0, winsize_y - cmd_height, cmd_width, cmd_height)) | 394 | |
370 | .unwrap(); | ||
371 | if self.command_box.is_empty() { | 395 | if self.command_box.is_empty() { |
372 | self.mode = Mode::Draw; | 396 | self.mode = Mode::Draw; |
373 | // show msg | 397 | // show msg |
@@ -376,7 +400,7 @@ impl<'ctx> AppState<'ctx> { | |||
376 | self.ttf_context, | 400 | self.ttf_context, |
377 | &self.message.text[..], | 401 | &self.message.text[..], |
378 | self.message.kind.into(), | 402 | self.message.kind.into(), |
379 | (0, winsize_y - cmd_height), | 403 | container.start, |
380 | ); | 404 | ); |
381 | return; | 405 | return; |
382 | } | 406 | } |
@@ -386,7 +410,7 @@ impl<'ctx> AppState<'ctx> { | |||
386 | self.ttf_context, | 410 | self.ttf_context, |
387 | &self.command_box.text[..], | 411 | &self.command_box.text[..], |
388 | WHITE, | 412 | WHITE, |
389 | (0, winsize_y - cmd_height), | 413 | container.start, |
390 | ); | 414 | ); |
391 | 415 | ||
392 | self.canvas.set_draw_color(PINK); | 416 | self.canvas.set_draw_color(PINK); |
@@ -397,14 +421,14 @@ impl<'ctx> AppState<'ctx> { | |||
397 | let prev_text_dim = font.size_of_latin1(prev_text.as_bytes()).unwrap(); | 421 | let prev_text_dim = font.size_of_latin1(prev_text.as_bytes()).unwrap(); |
398 | let cursor = rect!( | 422 | let cursor = rect!( |
399 | prev_text_dim.0, | 423 | prev_text_dim.0, |
400 | winsize_y - cmd_height + 2, | 424 | container.start.1 + 2, |
401 | 2, | 425 | 2, |
402 | cmd_height - 4 | 426 | container.height - 4 |
403 | ); | 427 | ); |
404 | self.canvas.fill_rect(cursor).unwrap(); | 428 | self.canvas.fill_rect(cursor).unwrap(); |
405 | } | 429 | } |
406 | 430 | ||
407 | fn draw_mouse(&mut self) { | 431 | fn draw_brush(&mut self) { |
408 | let cs = self.zoom as u32; | 432 | let cs = self.zoom as u32; |
409 | let pt = self.idx_at_coord(self.mouse); | 433 | let pt = self.idx_at_coord(self.mouse); |
410 | if matches!(self.brush, Brush::Circle { .. } | Brush::Line { .. }) { | 434 | if matches!(self.brush, Brush::Circle { .. } | Brush::Line { .. }) { |
@@ -434,7 +458,7 @@ impl<'ctx> AppState<'ctx> { | |||
434 | self.ttf_context, | 458 | self.ttf_context, |
435 | format!("{}°", positive_angle_with_x(from, to.into())), | 459 | format!("{}°", positive_angle_with_x(from, to.into())), |
436 | PINK, | 460 | PINK, |
437 | (self.mouse.0 as u32 + size, self.mouse.1 as u32 + size), | 461 | (self.mouse.0 + size as i32, self.mouse.1 + size as i32), |
438 | ); | 462 | ); |
439 | for MapPoint { x, y } in line.into_iter() { | 463 | for MapPoint { x, y } in line.into_iter() { |
440 | self.canvas.set_draw_color(PINK); | 464 | self.canvas.set_draw_color(PINK); |
@@ -499,7 +523,7 @@ impl<'ctx> AppState<'ctx> { | |||
499 | self.draw_symmetry(); | 523 | self.draw_symmetry(); |
500 | self.draw_statusline(); | 524 | self.draw_statusline(); |
501 | self.draw_command_box(); | 525 | self.draw_command_box(); |
502 | self.draw_mouse(); | 526 | self.draw_brush(); |
503 | } | 527 | } |
504 | 528 | ||
505 | fn redraw(&mut self) { | 529 | fn redraw(&mut self) { |