From 862cae5b0249153478ae4579272ff5af40c0e492 Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 13 Nov 2020 10:49:09 +0100 Subject: [PATCH] term: handle keyboard keys in the term_drawing example (#6810) --- examples/term.ui/term_drawing.v | 368 ++++++++++++++++++++------------ 1 file changed, 236 insertions(+), 132 deletions(-) diff --git a/examples/term.ui/term_drawing.v b/examples/term.ui/term_drawing.v index 9b4efea1af..3d7fc6521a 100644 --- a/examples/term.ui/term_drawing.v +++ b/examples/term.ui/term_drawing.v @@ -6,85 +6,83 @@ import term.ui as tui const ( colors = [ [ - tui.Color{239, 154, 154} - tui.Color{244, 143, 177} - tui.Color{206, 147, 216} - tui.Color{179, 157, 219} - tui.Color{159, 168, 218} - tui.Color{144, 202, 249} - tui.Color{129, 212, 250} - tui.Color{128, 222, 234} - tui.Color{128, 203, 196} - tui.Color{165, 214, 167} - tui.Color{197, 225, 165} - tui.Color{230, 238, 156} - tui.Color{255, 245, 157} - tui.Color{255, 224, 130} - tui.Color{255, 204, 128} - tui.Color{255, 171, 145} - tui.Color{188, 170, 164} - tui.Color{238, 238, 238} - tui.Color{176, 190, 197} - ], [ - tui.Color{244, 67, 54} - tui.Color{233, 30, 99} - tui.Color{156, 39, 176} - tui.Color{103, 58, 183} - tui.Color{63, 81, 181} - tui.Color{33, 150, 243} - tui.Color{3, 169, 244} - tui.Color{0, 188, 212} - tui.Color{0, 150, 136} - tui.Color{76, 175, 80} - tui.Color{139, 195, 74} - tui.Color{205, 220, 57} - tui.Color{255, 235, 59} - tui.Color{255, 193, 7} - tui.Color{255, 152, 0} - tui.Color{255, 87, 34} - tui.Color{121, 85, 72} - tui.Color{120, 120, 120} - tui.Color{96, 125, 139} - ], [ - tui.Color{198, 40, 40} - tui.Color{173, 20, 87} - tui.Color{106, 27, 154} - tui.Color{69, 39, 160} - tui.Color{40, 53, 147} - tui.Color{21, 101, 192} - tui.Color{2, 119, 189} - tui.Color{0, 131, 143} - tui.Color{0, 105, 92} - tui.Color{46, 125, 50} - tui.Color{85, 139, 47} - tui.Color{158, 157, 36} - tui.Color{249, 168, 37} - tui.Color{255, 143, 0} - tui.Color{239, 108, 0} - tui.Color{216, 67, 21} - tui.Color{78, 52, 46} - tui.Color{33, 33, 33} - tui.Color{55, 71, 79} - ] + tui.Color{239, 154, 154}, + tui.Color{244, 143, 177}, + tui.Color{206, 147, 216}, + tui.Color{179, 157, 219}, + tui.Color{159, 168, 218}, + tui.Color{144, 202, 249}, + tui.Color{129, 212, 250}, + tui.Color{128, 222, 234}, + tui.Color{128, 203, 196}, + tui.Color{165, 214, 167}, + tui.Color{197, 225, 165}, + tui.Color{230, 238, 156}, + tui.Color{255, 245, 157}, + tui.Color{255, 224, 130}, + tui.Color{255, 204, 128}, + tui.Color{255, 171, 145}, + tui.Color{188, 170, 164}, + tui.Color{238, 238, 238}, + tui.Color{176, 190, 197}, + ], + [ + tui.Color{244, 67, 54}, + tui.Color{233, 30, 99}, + tui.Color{156, 39, 176}, + tui.Color{103, 58, 183}, + tui.Color{63, 81, 181}, + tui.Color{33, 150, 243}, + tui.Color{3, 169, 244}, + tui.Color{0, 188, 212}, + tui.Color{0, 150, 136}, + tui.Color{76, 175, 80}, + tui.Color{139, 195, 74}, + tui.Color{205, 220, 57}, + tui.Color{255, 235, 59}, + tui.Color{255, 193, 7}, + tui.Color{255, 152, 0}, + tui.Color{255, 87, 34}, + tui.Color{121, 85, 72}, + tui.Color{120, 120, 120}, + tui.Color{96, 125, 139}, + ], + [ + tui.Color{198, 40, 40}, + tui.Color{173, 20, 87}, + tui.Color{106, 27, 154}, + tui.Color{69, 39, 160}, + tui.Color{40, 53, 147}, + tui.Color{21, 101, 192}, + tui.Color{2, 119, 189}, + tui.Color{0, 131, 143}, + tui.Color{0, 105, 92}, + tui.Color{46, 125, 50}, + tui.Color{85, 139, 47}, + tui.Color{158, 157, 36}, + tui.Color{249, 168, 37}, + tui.Color{255, 143, 0}, + tui.Color{239, 108, 0}, + tui.Color{216, 67, 21}, + tui.Color{78, 52, 46}, + tui.Color{33, 33, 33}, + tui.Color{55, 71, 79}, + ], ] ) const ( - frame_rate = 30 // fps + frame_rate = 30 // fps msg_display_time = 5 * frame_rate - - w = 200 - h = 100 - - space = ' ' - spaces = ' ' - - select_color = 'Select color:' - select_size = 'Size: + -' - - help_1 = '╭────────╮' - help_2 = '│ HELP │' - help_3 = '╰────────╯' + w = 200 + h = 100 + space = ' ' + spaces = ' ' + select_color = 'Select color: ' + select_size = 'Size: + -' + help_1 = '╭────────╮' + help_2 = '│ HELP │' + help_3 = '╰────────╯' ) struct App { @@ -96,41 +94,41 @@ mut: msg_hide_tick int primary_color tui.Color = colors[1][6] secondary_color tui.Color = colors[1][9] - drawing [][]tui.Color = [][]tui.Color{ len: h, init: []tui.Color{ len: w } } + color_index int + drawing [][]tui.Color = [][]tui.Color{len: h, init: []tui.Color{len: w}} size int = 1 should_redraw bool = true is_dragging bool } struct Point { +mut: x int y int } fn main() { mut app := &App{} - app.tui = tui.init( + app.tui = tui.init({ user_data: app frame_fn: frame event_fn: event - frame_rate: frame_rate hide_cursor: true - ) - + }) + app.mouse_pos.x = 40 + app.mouse_pos.y = 15 + app.tui.clear() app.tui.run() } fn frame(x voidptr) { mut app := &App(x) - mut redraw := app.should_redraw - if app.msg != '' && app.tui.frame_count >= app.msg_hide_tick { app.msg = '' redraw = true } - if redraw { app.render(false) app.should_redraw = false @@ -139,7 +137,6 @@ fn frame(x voidptr) { fn event(event &tui.Event, x voidptr) { mut app := &App(x) - match event.typ { .mouse_down { app.is_dragging = true @@ -148,56 +145,131 @@ fn event(event &tui.Event, x voidptr) { } else { app.paint(event) } - } .mouse_up { + } + .mouse_up { app.is_dragging = false - } .mouse_drag { - app.mouse_pos = { x: event.x, y: event.y } + } + .mouse_drag { + app.mouse_pos = { + x: event.x + y: event.y + } app.paint(event) - } .mouse_move { - app.mouse_pos = { x: event.x, y: event.y } - } .mouse_scroll { - if event.direction == .down { app.inc_size() } else { app.dec_size() } - } .key_down { + } + .mouse_move { + app.mouse_pos = { + x: event.x + y: event.y + } + } + .mouse_scroll { + if event.direction == .down { + app.inc_size() + } else { + app.dec_size() + } + } + .key_down { match event.code { + .j { + if event.modifiers & tui.shift != 0 { + app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) + } + app.mouse_pos.y++ + } + .k { + if event.modifiers & tui.shift != 0 { + app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) + } + app.mouse_pos.y-- + } + .h { + if event.modifiers & tui.shift != 0 { + app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) + } + app.mouse_pos.x -= 2 + } + .l { + if event.modifiers & tui.shift != 0 { + app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) + } + app.mouse_pos.x += 2 + } + .t { + mut c := if event.modifiers & tui.shift != 0 { app.color_index - 19 } else { app.color_index + + 19 } + if c < 0 { + c = 0 + } + cx := c % 19 + cy := (c / 19) % 3 + color := colors[cy][cx] + app.primary_color = color + app.color_index = c % (19 * 3) + } + .r { + mut c := if event.modifiers & tui.shift != 0 { app.color_index - 1 } else { app.color_index + + 1 } + if c < 0 { + c = 0 + } + cx := c % 19 + cy := (c / 19) % 3 + color := colors[cy][cx] + app.primary_color = color + app.color_index = c % (19 * 3) + } + .plus { + app.inc_size() + } + .minus { + app.dec_size() + } .c { - app.drawing = [][]tui.Color{ len: h, init: []tui.Color{ len: w } } - } .escape { + app.drawing = [][]tui.Color{len: h, init: []tui.Color{len: w}} + } + .q { app.render(true) exit(0) - } else {} + } + .escape { + app.render(true) + exit(0) + } + else {} } - } else {} + } + else {} } - app.should_redraw = true } fn (mut app App) render(paint_only bool) { app.tui.clear() - app.draw_header() app.draw_content() - if !paint_only { app.draw_footer() app.draw_cursor() } - app.tui.flush() } fn (mut app App) set_pixel(x_ int, y_ int, c tui.Color) { // Term coords start at 1, and adjust for the header x, y := x_ - 1, y_ - 4 - if y < 0 || app.tui.window_height - y < 3 { return } - if y >= app.drawing.len || x < 0 || x >= app.drawing[0].len { return } + if y < 0 || app.tui.window_height - y < 3 { + return + } + if y >= app.drawing.len || x < 0 || x >= app.drawing[0].len { + return + } app.drawing[y][x] = c } fn (mut app App) paint(event &tui.Event) { x_start, y_start := int(f32((event.x - 1) / 2) - app.size / 2 + 1), event.y - app.size / 2 color := if event.button == .primary { app.primary_color } else { app.secondary_color } - for x in x_start .. x_start + app.size { for y in y_start .. y_start + app.size { app.set_pixel(x, y, color) @@ -210,10 +282,9 @@ fn (mut app App) draw_content() { if h > app.drawing.len { h = app.drawing.len } - for row_idx, row in app.drawing[..h] { app.tui.set_cursor_position(0, row_idx + 4) - mut last := tui.Color{ 0, 0, 0 } + mut last := tui.Color{0, 0, 0} for cell in row[..w] { if cell.r == 0 && cell.g == 0 && cell.b == 0 { if !(cell.r == last.r && cell.g == last.g && cell.b == last.b) { @@ -236,22 +307,26 @@ fn (mut app App) draw_cursor() { // inside the horizontal separators return } - - cursor_color := if app.is_dragging { tui.Color{ 220, 220, 220 } } else { tui.Color{ 160, 160, 160 } } + cursor_color := if app.is_dragging { tui.Color{220, 220, 220} } else { tui.Color{160, 160, 160} } app.tui.set_bg_color(cursor_color) - if app.mouse_pos.y >= 3 && app.mouse_pos.y <= app.tui.window_height - 4 { // inside the main content mut x_start := int(f32((app.mouse_pos.x - 1) / 2) - app.size / 2 + 1) * 2 - 1 mut y_start := app.mouse_pos.y - app.size / 2 mut x_end := x_start + app.size * 2 - 1 mut y_end := y_start + app.size - 1 - - if x_start < 1 { x_start = 1 } - if y_start < 4 { y_start = 4 } - if x_end > app.tui.window_width { x_end = app.tui.window_width } - if y_end > app.tui.window_height - 5 { y_end = app.tui.window_height - 5 } - + if x_start < 1 { + x_start = 1 + } + if y_start < 4 { + y_start = 4 + } + if x_end > app.tui.window_width { + x_end = app.tui.window_width + } + if y_end > app.tui.window_height - 5 { + y_end = app.tui.window_height - 5 + } app.tui.draw_rect(x_start, y_start, x_end, y_end) } else { app.tui.draw_text(app.mouse_pos.x, app.mouse_pos.y, space) @@ -261,37 +336,52 @@ fn (mut app App) draw_cursor() { fn (mut app App) draw_header() { if app.msg != '' { - app.tui.set_color(r: 0, g: 0, b: 0) - app.tui.set_bg_color(r: 220, g: 220, b: 220) + app.tui.set_color({ + r: 0 + g: 0 + b: 0 + }) + app.tui.set_bg_color({ + r: 220 + g: 220 + b: 220 + }) app.tui.draw_text(0, 0, ' $app.msg ') app.tui.reset() - } - + } app.tui.draw_text(3, 2, /* 'tick: $app.tui.frame_count | ' + */ 'terminal size: ($app.tui.window_width, $app.tui.window_height) | primary color: $app.primary_color.hex() | secondary color: $app.secondary_color.hex()') app.tui.horizontal_separator(3) } +fn (mut app App) current_color(x int, y int) bool { + return app.color_index == x + (y * 19) +} + fn (mut app App) draw_footer() { ww, wh := app.tui.window_width, app.tui.window_height - app.tui.horizontal_separator(wh - 4) - for i, color_row in colors { for j, color in color_row { x := j * 3 + 19 y := wh - 3 + i - app.tui.set_bg_color(color) - app.tui.draw_rect(x, y, x+1, y) + if app.current_color(j, i) { + app.tui.set_color(tui.Color{0, 0, 0}) + app.tui.draw_text(x, y, '><') + app.tui.reset_color() + } else { + app.tui.draw_rect(x, y, x + 1, y) + } } } app.tui.reset_bg_color() - app.tui.draw_text(3, wh - 3, select_color) + app.tui.set_bg_color(app.primary_color) + app.tui.draw_text(3 + select_color.len, wh - 3, ' ') + app.tui.reset_bg_color() app.tui.bold() - app.tui.draw_text(3, wh - 1, select_size) + app.tui.draw_text(3, wh - 1, '$select_size $app.size') app.tui.reset() - if ww >= 90 { app.tui.draw_text(80, wh - 3, help_1) app.tui.draw_text(80, wh - 2, help_2) @@ -301,13 +391,17 @@ fn (mut app App) draw_footer() { [inline] fn (mut app App) inc_size() { - if app.size < 20 { app.size++ } + if app.size < 20 { + app.size++ + } app.show_msg('inc. size: $app.size', 1) } [inline] fn (mut app App) dec_size() { - if app.size > 1 { app.size-- } + if app.size > 1 { + app.size-- + } app.show_msg('dec. size: $app.size', 1) } @@ -316,15 +410,25 @@ fn (mut app App) footer_click(event &tui.Event) { match event.x { 8...11 { app.inc_size() - } 12...15 { + } + 12...15 { app.dec_size() - } 18...75 { - if (event.x % 3) == 0 { return } // Inside the gap between tiles + } + 18...75 { + if (event.x % 3) == 0 { + // Inside the gap between tiles + return + } idx := footer_y * 19 - 6 + event.x / 3 color := colors[idx / 19][idx % 19] - if event.button == .primary { app.primary_color = color } else { app.secondary_color = color } - app.show_msg('set ${event.button.str().to_lower()} color idx: $idx', 1) - } else {} + if event.button == .primary { + app.primary_color = color + } else { + app.secondary_color = color + } + app.show_msg('set $event.button.str().to_lower() color idx: $idx', 1) + } + else {} } }