From fdc0cd4c039f70ffec4eea33fd573eb76c1d5645 Mon Sep 17 00:00:00 2001 From: Larpon Date: Tue, 17 Nov 2020 15:08:35 +0100 Subject: [PATCH] term.ui: add dashed lines and rectangles (#6848) --- vlib/term/ui/ui.v | 87 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 16 deletions(-) diff --git a/vlib/term/ui/ui.v b/vlib/term/ui/ui.v index 54b098e94a..7be42b68a9 100644 --- a/vlib/term/ui/ui.v +++ b/vlib/term/ui/ui.v @@ -10,7 +10,7 @@ pub: } pub fn (c Color) hex() string { - return '#${c.r.hex()}${c.g.hex()}${c.b.hex()}' + return '#$c.r.hex()$c.g.hex()$c.b.hex()' } // Synchronized Updates spec, designed to avoid tearing during renders @@ -22,7 +22,9 @@ const ( [inline] pub fn (mut ctx Context) write(s string) { - if s == '' { return } + if s == '' { + return + } ctx.print_buf.push_many(s.str, s.len) } @@ -103,29 +105,26 @@ pub fn (mut ctx Context) draw_text(x int, y int, s string) { pub fn (mut ctx Context) draw_line(x int, y int, x2 int, y2 int) { min_x, min_y := if x < x2 { x } else { x2 }, if y < y2 { y } else { y2 } max_x, _ := if x > x2 { x } else { x2 }, if y > y2 { y } else { y2 } - if y == y2 { // Horizontal line, performance improvement ctx.set_cursor_position(min_x, min_y) ctx.write(strings.repeat(` `, max_x + 1 - min_x)) return } - // Draw the various points with Bresenham's line algorithm: mut x0, x1 := x, x2 mut y0, y1 := y, y2 - sx := if x0 < x1 { 1 } else { -1 } sy := if y0 < y1 { 1 } else { -1 } dx := if x0 < x1 { x1 - x0 } else { x0 - x1 } dy := if y0 < y1 { y0 - y1 } else { y1 - y0 } // reversed - mut err := dx + dy - for { // res << Segment{ x0, y0 } ctx.draw_point(x0, y0) - if x0 == x1 && y0 == y1 { break } + if x0 == x1 && y0 == y1 { + break + } e2 := 2 * err if e2 >= dy { err += dy @@ -138,29 +137,79 @@ pub fn (mut ctx Context) draw_line(x int, y int, x2 int, y2 int) { } } +pub fn (mut ctx Context) draw_dashed_line(x int, y int, x2 int, y2 int) { + // Draw the various points with Bresenham's line algorithm: + mut x0, x1 := x, x2 + mut y0, y1 := y, y2 + sx := if x0 < x1 { 1 } else { -1 } + sy := if y0 < y1 { 1 } else { -1 } + dx := if x0 < x1 { x1 - x0 } else { x0 - x1 } + dy := if y0 < y1 { y0 - y1 } else { y1 - y0 } // reversed + mut err := dx + dy + mut i := 0 + for { + if i % 2 == 0 { + ctx.draw_point(x0, y0) + } + if x0 == x1 && y0 == y1 { + break + } + e2 := 2 * err + if e2 >= dy { + err += dy + x0 += sx + } + if e2 <= dx { + err += dx + y0 += sy + } + i++ + } +} + pub fn (mut ctx Context) draw_rect(x int, y int, x2 int, y2 int) { if y == y2 || x == x2 { ctx.draw_line(x, y, x2, y2) return } - - min_y, max_y := if y < y2 { y } else { y2 }, if y > y2 { y } else { y2 } - + min_y, max_y := if y < y2 { y, y2 } else { y2, y } for y_pos in min_y .. max_y + 1 { ctx.draw_line(x, y_pos, x2, y_pos) } } +pub fn (mut ctx Context) draw_empty_dashed_rect(x int, y int, x2 int, y2 int) { + if y == y2 || x == x2 { + ctx.draw_dashed_line(x, y, x2, y2) + return + } + + min_x, max_x := if x < x2 { x, x2 } else { x2, x } + min_y, max_y := if y < y2 { y, y2 } else { y2, y } + + ctx.draw_dashed_line(min_x, min_y, max_x, min_y) + ctx.draw_dashed_line(min_x, min_y, min_x, max_y) + if (max_y - min_y) & 1 == 0 { + ctx.draw_dashed_line(min_x, max_y, max_x, max_y) + } else { + ctx.draw_dashed_line(min_x + 1, max_y, max_x, max_y) + } + if (max_x - min_x) & 1 == 0 { + ctx.draw_dashed_line(max_x, min_y, max_x, max_y) + } else { + ctx.draw_dashed_line(max_x, min_y + 1, max_x, max_y) + } +} + pub fn (mut ctx Context) draw_empty_rect(x int, y int, x2 int, y2 int) { if y == y2 || x == x2 { ctx.draw_line(x, y, x2, y2) return } - - ctx.draw_line(x, y, x2, y) - ctx.draw_line(x, y2, x2, y2) - ctx.draw_line(x, y, x, y2) - ctx.draw_line(x2, y, x2, y2) + ctx.draw_line(x, y, x2, y) + ctx.draw_line(x, y2, x2, y2) + ctx.draw_line(x, y, x, y2) + ctx.draw_line(x2, y, x2, y2) } [inline] @@ -168,3 +217,9 @@ pub fn (mut ctx Context) horizontal_separator(y int) { ctx.set_cursor_position(0, y) ctx.write(strings.repeat(/* `⎽` */`-`, ctx.window_width)) } + + +[inline] +fn abs(a int) int { + return if a < 0 { -a } else { a } +}