term: handle keyboard keys in the term_drawing example (#6810)

pull/6808/head
pancake 2020-11-13 10:49:09 +01:00 committed by GitHub
parent f6e54dc027
commit 862cae5b02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 236 additions and 132 deletions

View File

@ -6,82 +6,80 @@ import term.ui as tui
const ( const (
colors = [ colors = [
[ [
tui.Color{239, 154, 154} tui.Color{239, 154, 154},
tui.Color{244, 143, 177} tui.Color{244, 143, 177},
tui.Color{206, 147, 216} tui.Color{206, 147, 216},
tui.Color{179, 157, 219} tui.Color{179, 157, 219},
tui.Color{159, 168, 218} tui.Color{159, 168, 218},
tui.Color{144, 202, 249} tui.Color{144, 202, 249},
tui.Color{129, 212, 250} tui.Color{129, 212, 250},
tui.Color{128, 222, 234} tui.Color{128, 222, 234},
tui.Color{128, 203, 196} tui.Color{128, 203, 196},
tui.Color{165, 214, 167} tui.Color{165, 214, 167},
tui.Color{197, 225, 165} tui.Color{197, 225, 165},
tui.Color{230, 238, 156} tui.Color{230, 238, 156},
tui.Color{255, 245, 157} tui.Color{255, 245, 157},
tui.Color{255, 224, 130} tui.Color{255, 224, 130},
tui.Color{255, 204, 128} tui.Color{255, 204, 128},
tui.Color{255, 171, 145} tui.Color{255, 171, 145},
tui.Color{188, 170, 164} tui.Color{188, 170, 164},
tui.Color{238, 238, 238} tui.Color{238, 238, 238},
tui.Color{176, 190, 197} tui.Color{176, 190, 197},
], [ ],
tui.Color{244, 67, 54} [
tui.Color{233, 30, 99} tui.Color{244, 67, 54},
tui.Color{156, 39, 176} tui.Color{233, 30, 99},
tui.Color{103, 58, 183} tui.Color{156, 39, 176},
tui.Color{63, 81, 181} tui.Color{103, 58, 183},
tui.Color{33, 150, 243} tui.Color{63, 81, 181},
tui.Color{3, 169, 244} tui.Color{33, 150, 243},
tui.Color{0, 188, 212} tui.Color{3, 169, 244},
tui.Color{0, 150, 136} tui.Color{0, 188, 212},
tui.Color{76, 175, 80} tui.Color{0, 150, 136},
tui.Color{139, 195, 74} tui.Color{76, 175, 80},
tui.Color{205, 220, 57} tui.Color{139, 195, 74},
tui.Color{255, 235, 59} tui.Color{205, 220, 57},
tui.Color{255, 193, 7} tui.Color{255, 235, 59},
tui.Color{255, 152, 0} tui.Color{255, 193, 7},
tui.Color{255, 87, 34} tui.Color{255, 152, 0},
tui.Color{121, 85, 72} tui.Color{255, 87, 34},
tui.Color{120, 120, 120} tui.Color{121, 85, 72},
tui.Color{96, 125, 139} 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{198, 40, 40},
tui.Color{69, 39, 160} tui.Color{173, 20, 87},
tui.Color{40, 53, 147} tui.Color{106, 27, 154},
tui.Color{21, 101, 192} tui.Color{69, 39, 160},
tui.Color{2, 119, 189} tui.Color{40, 53, 147},
tui.Color{0, 131, 143} tui.Color{21, 101, 192},
tui.Color{0, 105, 92} tui.Color{2, 119, 189},
tui.Color{46, 125, 50} tui.Color{0, 131, 143},
tui.Color{85, 139, 47} tui.Color{0, 105, 92},
tui.Color{158, 157, 36} tui.Color{46, 125, 50},
tui.Color{249, 168, 37} tui.Color{85, 139, 47},
tui.Color{255, 143, 0} tui.Color{158, 157, 36},
tui.Color{239, 108, 0} tui.Color{249, 168, 37},
tui.Color{216, 67, 21} tui.Color{255, 143, 0},
tui.Color{78, 52, 46} tui.Color{239, 108, 0},
tui.Color{33, 33, 33} tui.Color{216, 67, 21},
tui.Color{55, 71, 79} tui.Color{78, 52, 46},
] tui.Color{33, 33, 33},
tui.Color{55, 71, 79},
],
] ]
) )
const ( const (
frame_rate = 30 // fps frame_rate = 30 // fps
msg_display_time = 5 * frame_rate msg_display_time = 5 * frame_rate
w = 200 w = 200
h = 100 h = 100
space = ' ' space = ' '
spaces = ' ' spaces = ' '
select_color = 'Select color: '
select_color = 'Select color:'
select_size = 'Size: ' select_size = 'Size: '
help_1 = '' help_1 = ''
help_2 = ' HELP ' help_2 = ' HELP '
help_3 = '' help_3 = ''
@ -96,41 +94,41 @@ mut:
msg_hide_tick int msg_hide_tick int
primary_color tui.Color = colors[1][6] primary_color tui.Color = colors[1][6]
secondary_color tui.Color = colors[1][9] 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 size int = 1
should_redraw bool = true should_redraw bool = true
is_dragging bool is_dragging bool
} }
struct Point { struct Point {
mut:
x int x int
y int y int
} }
fn main() { fn main() {
mut app := &App{} mut app := &App{}
app.tui = tui.init( app.tui = tui.init({
user_data: app user_data: app
frame_fn: frame frame_fn: frame
event_fn: event event_fn: event
frame_rate: frame_rate frame_rate: frame_rate
hide_cursor: true hide_cursor: true
) })
app.mouse_pos.x = 40
app.mouse_pos.y = 15
app.tui.clear()
app.tui.run() app.tui.run()
} }
fn frame(x voidptr) { fn frame(x voidptr) {
mut app := &App(x) mut app := &App(x)
mut redraw := app.should_redraw mut redraw := app.should_redraw
if app.msg != '' && app.tui.frame_count >= app.msg_hide_tick { if app.msg != '' && app.tui.frame_count >= app.msg_hide_tick {
app.msg = '' app.msg = ''
redraw = true redraw = true
} }
if redraw { if redraw {
app.render(false) app.render(false)
app.should_redraw = false app.should_redraw = false
@ -139,7 +137,6 @@ fn frame(x voidptr) {
fn event(event &tui.Event, x voidptr) { fn event(event &tui.Event, x voidptr) {
mut app := &App(x) mut app := &App(x)
match event.typ { match event.typ {
.mouse_down { .mouse_down {
app.is_dragging = true app.is_dragging = true
@ -148,56 +145,131 @@ fn event(event &tui.Event, x voidptr) {
} else { } else {
app.paint(event) app.paint(event)
} }
} .mouse_up { }
.mouse_up {
app.is_dragging = false 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) app.paint(event)
} .mouse_move { }
app.mouse_pos = { x: event.x, y: event.y } .mouse_move {
} .mouse_scroll { app.mouse_pos = {
if event.direction == .down { app.inc_size() } else { app.dec_size() } x: event.x
} .key_down { y: event.y
}
}
.mouse_scroll {
if event.direction == .down {
app.inc_size()
} else {
app.dec_size()
}
}
.key_down {
match event.code { 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 { .c {
app.drawing = [][]tui.Color{ len: h, init: []tui.Color{ len: w } } app.drawing = [][]tui.Color{len: h, init: []tui.Color{len: w}}
} .escape { }
.q {
app.render(true) app.render(true)
exit(0) exit(0)
} else {}
} }
} else {} .escape {
app.render(true)
exit(0)
}
else {}
}
}
else {}
} }
app.should_redraw = true app.should_redraw = true
} }
fn (mut app App) render(paint_only bool) { fn (mut app App) render(paint_only bool) {
app.tui.clear() app.tui.clear()
app.draw_header() app.draw_header()
app.draw_content() app.draw_content()
if !paint_only { if !paint_only {
app.draw_footer() app.draw_footer()
app.draw_cursor() app.draw_cursor()
} }
app.tui.flush() app.tui.flush()
} }
fn (mut app App) set_pixel(x_ int, y_ int, c tui.Color) { fn (mut app App) set_pixel(x_ int, y_ int, c tui.Color) {
// Term coords start at 1, and adjust for the header // Term coords start at 1, and adjust for the header
x, y := x_ - 1, y_ - 4 x, y := x_ - 1, y_ - 4
if y < 0 || app.tui.window_height - y < 3 { return } if y < 0 || app.tui.window_height - y < 3 {
if y >= app.drawing.len || x < 0 || x >= app.drawing[0].len { return } return
}
if y >= app.drawing.len || x < 0 || x >= app.drawing[0].len {
return
}
app.drawing[y][x] = c app.drawing[y][x] = c
} }
fn (mut app App) paint(event &tui.Event) { 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 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 } color := if event.button == .primary { app.primary_color } else { app.secondary_color }
for x in x_start .. x_start + app.size { for x in x_start .. x_start + app.size {
for y in y_start .. y_start + app.size { for y in y_start .. y_start + app.size {
app.set_pixel(x, y, color) app.set_pixel(x, y, color)
@ -210,10 +282,9 @@ fn (mut app App) draw_content() {
if h > app.drawing.len { if h > app.drawing.len {
h = app.drawing.len h = app.drawing.len
} }
for row_idx, row in app.drawing[..h] { for row_idx, row in app.drawing[..h] {
app.tui.set_cursor_position(0, row_idx + 4) 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] { for cell in row[..w] {
if cell.r == 0 && cell.g == 0 && cell.b == 0 { if cell.r == 0 && cell.g == 0 && cell.b == 0 {
if !(cell.r == last.r && cell.g == last.g && cell.b == last.b) { 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 // inside the horizontal separators
return 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) app.tui.set_bg_color(cursor_color)
if app.mouse_pos.y >= 3 && app.mouse_pos.y <= app.tui.window_height - 4 { if app.mouse_pos.y >= 3 && app.mouse_pos.y <= app.tui.window_height - 4 {
// inside the main content // inside the main content
mut x_start := int(f32((app.mouse_pos.x - 1) / 2) - app.size / 2 + 1) * 2 - 1 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 y_start := app.mouse_pos.y - app.size / 2
mut x_end := x_start + app.size * 2 - 1 mut x_end := x_start + app.size * 2 - 1
mut y_end := y_start + app.size - 1 mut y_end := y_start + app.size - 1
if x_start < 1 {
if x_start < 1 { 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_start < 4 {
if y_end > app.tui.window_height - 5 { y_end = app.tui.window_height - 5 } 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) app.tui.draw_rect(x_start, y_start, x_end, y_end)
} else { } else {
app.tui.draw_text(app.mouse_pos.x, app.mouse_pos.y, space) 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() { fn (mut app App) draw_header() {
if app.msg != '' { if app.msg != '' {
app.tui.set_color(r: 0, g: 0, b: 0) app.tui.set_color({
app.tui.set_bg_color(r: 220, g: 220, b: 220) 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.draw_text(0, 0, ' $app.msg ')
app.tui.reset() 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.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) 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() { fn (mut app App) draw_footer() {
ww, wh := app.tui.window_width, app.tui.window_height ww, wh := app.tui.window_width, app.tui.window_height
app.tui.horizontal_separator(wh - 4) app.tui.horizontal_separator(wh - 4)
for i, color_row in colors { for i, color_row in colors {
for j, color in color_row { for j, color in color_row {
x := j * 3 + 19 x := j * 3 + 19
y := wh - 3 + i y := wh - 3 + i
app.tui.set_bg_color(color) 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.reset_bg_color()
app.tui.draw_text(3, wh - 3, select_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.bold()
app.tui.draw_text(3, wh - 1, select_size) app.tui.draw_text(3, wh - 1, '$select_size $app.size')
app.tui.reset() app.tui.reset()
if ww >= 90 { if ww >= 90 {
app.tui.draw_text(80, wh - 3, help_1) app.tui.draw_text(80, wh - 3, help_1)
app.tui.draw_text(80, wh - 2, help_2) app.tui.draw_text(80, wh - 2, help_2)
@ -301,13 +391,17 @@ fn (mut app App) draw_footer() {
[inline] [inline]
fn (mut app App) inc_size() { 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) app.show_msg('inc. size: $app.size', 1)
} }
[inline] [inline]
fn (mut app App) dec_size() { 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) app.show_msg('dec. size: $app.size', 1)
} }
@ -316,15 +410,25 @@ fn (mut app App) footer_click(event &tui.Event) {
match event.x { match event.x {
8...11 { 8...11 {
app.inc_size() app.inc_size()
} 12...15 { }
12...15 {
app.dec_size() 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 idx := footer_y * 19 - 6 + event.x / 3
color := colors[idx / 19][idx % 19] color := colors[idx / 19][idx % 19]
if event.button == .primary { app.primary_color = color } else { app.secondary_color = color } if event.button == .primary {
app.show_msg('set ${event.button.str().to_lower()} color idx: $idx', 1) app.primary_color = color
} else {} } else {
app.secondary_color = color
}
app.show_msg('set $event.button.str().to_lower() color idx: $idx', 1)
}
else {}
} }
} }