766 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			766 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			V
		
	
	
module gg
 | 
						|
 | 
						|
import gx
 | 
						|
import js.dom
 | 
						|
 | 
						|
pub enum DOMEventType {
 | 
						|
	invalid
 | 
						|
	key_down
 | 
						|
	key_up
 | 
						|
	char
 | 
						|
	mouse_down
 | 
						|
	mouse_up
 | 
						|
	mouse_scroll
 | 
						|
	mouse_move
 | 
						|
	mouse_enter
 | 
						|
	mouse_leave
 | 
						|
	touches_began
 | 
						|
	touches_moved
 | 
						|
	touches_ended
 | 
						|
	touches_cancelled
 | 
						|
	resized
 | 
						|
	iconified
 | 
						|
	restored
 | 
						|
	focused
 | 
						|
	unfocused
 | 
						|
	suspended
 | 
						|
	resumed
 | 
						|
	update_cursor
 | 
						|
	quit_requested
 | 
						|
	clipboard_pasted
 | 
						|
	files_droped
 | 
						|
	num
 | 
						|
}
 | 
						|
 | 
						|
pub struct Event {
 | 
						|
pub mut:
 | 
						|
	frame_count  u64
 | 
						|
	typ          DOMEventType
 | 
						|
	key_code     KeyCode
 | 
						|
	char_code    u32
 | 
						|
	key_repeat   bool
 | 
						|
	modifiers    u32
 | 
						|
	mouse_button MouseButton
 | 
						|
	mouse_x      f32
 | 
						|
	mouse_y      f32
 | 
						|
	mouse_dx     f32
 | 
						|
	mouse_dy     f32
 | 
						|
	scroll_x     f32
 | 
						|
	scroll_y     f32
 | 
						|
	// todo(playX): add touches API support in js.dom
 | 
						|
	// num_touches        int
 | 
						|
	// touches            [8]TouchPoint
 | 
						|
	window_width       int
 | 
						|
	window_height      int
 | 
						|
	framebuffer_width  int
 | 
						|
	framebuffer_height int
 | 
						|
}
 | 
						|
 | 
						|
pub enum DOMMouseButton {
 | 
						|
	invalid = -1
 | 
						|
	left = 0
 | 
						|
	right = 1
 | 
						|
	middle = 2
 | 
						|
}
 | 
						|
 | 
						|
pub enum DOMModifier {
 | 
						|
	shift = 1 //(1<<0)
 | 
						|
	ctrl = 2 //(1<<1)
 | 
						|
	alt = 4 //(1<<2)
 | 
						|
	super = 8 //(1<<3)
 | 
						|
	lmb = 0x100
 | 
						|
	rmb = 0x200
 | 
						|
	mmb = 0x400
 | 
						|
}
 | 
						|
 | 
						|
pub enum DOMKeyCode {
 | 
						|
	invalid = 0
 | 
						|
	space = 32
 | 
						|
	apostrophe = 39 //'
 | 
						|
	comma = 44 //,
 | 
						|
	minus = 45 //-
 | 
						|
	period = 46 //.
 | 
						|
	slash = 47 ///
 | 
						|
	_0 = 48
 | 
						|
	_1 = 49
 | 
						|
	_2 = 50
 | 
						|
	_3 = 51
 | 
						|
	_4 = 52
 | 
						|
	_5 = 53
 | 
						|
	_6 = 54
 | 
						|
	_7 = 55
 | 
						|
	_8 = 56
 | 
						|
	_9 = 57
 | 
						|
	semicolon = 59 //;
 | 
						|
	equal = 61 //=
 | 
						|
	a = 65
 | 
						|
	b = 66
 | 
						|
	c = 67
 | 
						|
	d = 68
 | 
						|
	e = 69
 | 
						|
	f = 70
 | 
						|
	g = 71
 | 
						|
	h = 72
 | 
						|
	i = 73
 | 
						|
	j = 74
 | 
						|
	k = 75
 | 
						|
	l = 76
 | 
						|
	m = 77
 | 
						|
	n = 78
 | 
						|
	o = 79
 | 
						|
	p = 80
 | 
						|
	q = 81
 | 
						|
	r = 82
 | 
						|
	s = 83
 | 
						|
	t = 84
 | 
						|
	u = 85
 | 
						|
	v = 86
 | 
						|
	w = 87
 | 
						|
	x = 88
 | 
						|
	y = 89
 | 
						|
	z = 90
 | 
						|
	left_bracket = 91 //[
 | 
						|
	backslash = 92 //\
 | 
						|
	right_bracket = 93 //]
 | 
						|
	grave_accent = 96 //`
 | 
						|
	world_1 = 161 // non-us #1
 | 
						|
	world_2 = 162 // non-us #2
 | 
						|
	escape = 256
 | 
						|
	enter = 257
 | 
						|
	tab = 258
 | 
						|
	backspace = 259
 | 
						|
	insert = 260
 | 
						|
	delete = 261
 | 
						|
	right = 262
 | 
						|
	left = 263
 | 
						|
	down = 264
 | 
						|
	up = 265
 | 
						|
	page_up = 266
 | 
						|
	page_down = 267
 | 
						|
	home = 268
 | 
						|
	end = 269
 | 
						|
	caps_lock = 280
 | 
						|
	scroll_lock = 281
 | 
						|
	num_lock = 282
 | 
						|
	print_screen = 283
 | 
						|
	pause = 284
 | 
						|
	f1 = 290
 | 
						|
	f2 = 291
 | 
						|
	f3 = 292
 | 
						|
	f4 = 293
 | 
						|
	f5 = 294
 | 
						|
	f6 = 295
 | 
						|
	f7 = 296
 | 
						|
	f8 = 297
 | 
						|
	f9 = 298
 | 
						|
	f10 = 299
 | 
						|
	f11 = 300
 | 
						|
	f12 = 301
 | 
						|
	f13 = 302
 | 
						|
	f14 = 303
 | 
						|
	f15 = 304
 | 
						|
	f16 = 305
 | 
						|
	f17 = 306
 | 
						|
	f18 = 307
 | 
						|
	f19 = 308
 | 
						|
	f20 = 309
 | 
						|
	f21 = 310
 | 
						|
	f22 = 311
 | 
						|
	f23 = 312
 | 
						|
	f24 = 313
 | 
						|
	f25 = 314
 | 
						|
	kp_0 = 320
 | 
						|
	kp_1 = 321
 | 
						|
	kp_2 = 322
 | 
						|
	kp_3 = 323
 | 
						|
	kp_4 = 324
 | 
						|
	kp_5 = 325
 | 
						|
	kp_6 = 326
 | 
						|
	kp_7 = 327
 | 
						|
	kp_8 = 328
 | 
						|
	kp_9 = 329
 | 
						|
	kp_decimal = 330
 | 
						|
	kp_divide = 331
 | 
						|
	kp_multiply = 332
 | 
						|
	kp_subtract = 333
 | 
						|
	kp_add = 334
 | 
						|
	kp_enter = 335
 | 
						|
	kp_equal = 336
 | 
						|
	left_shift = 340
 | 
						|
	left_control = 341
 | 
						|
	left_alt = 342
 | 
						|
	left_super = 343
 | 
						|
	right_shift = 344
 | 
						|
	right_control = 345
 | 
						|
	right_alt = 346
 | 
						|
	right_super = 347
 | 
						|
	menu = 348
 | 
						|
}
 | 
						|
 | 
						|
pub struct Config {
 | 
						|
pub:
 | 
						|
	width         int
 | 
						|
	height        int
 | 
						|
	use_ortho     bool // unused, still here just for backwards compatibility
 | 
						|
	retina        bool
 | 
						|
	resizable     bool
 | 
						|
	user_data     voidptr
 | 
						|
	font_size     int
 | 
						|
	create_window bool
 | 
						|
	// window_user_ptr voidptr
 | 
						|
	window_title      string
 | 
						|
	borderless_window bool
 | 
						|
	always_on_top     bool
 | 
						|
	bg_color          gx.Color
 | 
						|
	init_fn           FNCb   = voidptr(0)
 | 
						|
	frame_fn          FNCb   = voidptr(0)
 | 
						|
	native_frame_fn   FNCb   = voidptr(0)
 | 
						|
	cleanup_fn        FNCb   = voidptr(0)
 | 
						|
	fail_fn           FNFail = voidptr(0)
 | 
						|
	//
 | 
						|
	event_fn FNEvent = voidptr(0)
 | 
						|
	quit_fn  FNEvent = voidptr(0)
 | 
						|
	//
 | 
						|
	keydown_fn FNKeyDown = voidptr(0)
 | 
						|
	keyup_fn   FNKeyUp   = voidptr(0)
 | 
						|
	char_fn    FNChar    = voidptr(0)
 | 
						|
	//
 | 
						|
	move_fn    FNMove    = voidptr(0)
 | 
						|
	click_fn   FNClick   = voidptr(0)
 | 
						|
	unclick_fn FNUnClick = voidptr(0)
 | 
						|
	leave_fn   FNEvent   = voidptr(0)
 | 
						|
	enter_fn   FNEvent   = voidptr(0)
 | 
						|
	resized_fn FNEvent   = voidptr(0)
 | 
						|
	scroll_fn  FNEvent   = voidptr(0)
 | 
						|
	// wait_events       bool // set this to true for UIs, to save power
 | 
						|
	fullscreen    bool
 | 
						|
	scale         f32 = 1.0
 | 
						|
	sample_count  int
 | 
						|
	swap_interval int = 1 // 1 = 60fps, 2 = 30fps etc. The preferred swap interval (ignored on some platforms)
 | 
						|
	// ved needs this
 | 
						|
	// init_text bool
 | 
						|
	font_path             string
 | 
						|
	custom_bold_font_path string
 | 
						|
	ui_mode               bool // refreshes only on events to save CPU usage
 | 
						|
	// font bytes for embedding
 | 
						|
	font_bytes_normal []u8
 | 
						|
	font_bytes_bold   []u8
 | 
						|
	font_bytes_mono   []u8
 | 
						|
	font_bytes_italic []u8
 | 
						|
	native_rendering  bool // Cocoa on macOS/iOS, GDI+ on Windows
 | 
						|
	// drag&drop
 | 
						|
	enable_dragndrop             bool // enable file dropping (drag'n'drop), default is false
 | 
						|
	max_dropped_files            int = 1 // max number of dropped files to process (default: 1)
 | 
						|
	max_dropped_file_path_length int = 2048 // max length in bytes of a dropped UTF-8 file path (default: 2048)
 | 
						|
	canvas                       string
 | 
						|
}
 | 
						|
 | 
						|
const size = Size{0, 0}
 | 
						|
 | 
						|
pub fn window_size() Size {
 | 
						|
	return gg.size
 | 
						|
}
 | 
						|
 | 
						|
pub struct Context {
 | 
						|
mut:
 | 
						|
	render_text   bool = true
 | 
						|
	image_cache   []Image
 | 
						|
	needs_refresh bool = true
 | 
						|
	ticks         int
 | 
						|
pub mut:
 | 
						|
	scale         f32 = 1.0
 | 
						|
	width         int
 | 
						|
	height        int
 | 
						|
	window        JS.Window    [noinit]
 | 
						|
	config        Config
 | 
						|
	user_data     voidptr
 | 
						|
	ui_mode       bool
 | 
						|
	frame         u64
 | 
						|
	mbtn_mask     u8
 | 
						|
	mouse_buttons MouseButtons
 | 
						|
	mouse_pos_x   int
 | 
						|
	mouse_pos_y   int
 | 
						|
	mouse_dx      int
 | 
						|
	mouse_dy      int
 | 
						|
	scroll_x      int
 | 
						|
	scroll_y      int
 | 
						|
	//
 | 
						|
	key_modifiers     Modifier // the current key modifiers
 | 
						|
	key_repeat        bool     // whether the pressed key was an autorepeated one
 | 
						|
	pressed_keys      [key_code_max]bool // an array representing all currently pressed keys
 | 
						|
	pressed_keys_edge [key_code_max]bool // true when the previous state of pressed_keys,
 | 
						|
	context           JS.CanvasRenderingContext2D [noinit]
 | 
						|
	canvas            JS.HTMLCanvasElement        [noinit]
 | 
						|
	// *before* the current event was different
 | 
						|
}
 | 
						|
 | 
						|
fn get_canvas(elem JS.HTMLElement) &JS.HTMLCanvasElement {
 | 
						|
	match elem {
 | 
						|
		JS.HTMLCanvasElement {
 | 
						|
			return elem
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			panic('gg: element is not an HTMLCanvasElement')
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
fn get_context(canvas JS.HTMLCanvasElement) JS.CanvasRenderingContext2D {
 | 
						|
	ctx := canvas.getContext('2d'.str, js_undefined()) or { panic('cannot get context') }
 | 
						|
	match ctx {
 | 
						|
		JS.CanvasRenderingContext2D {
 | 
						|
			return ctx
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			panic('failed to get 2D context')
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
pub fn new_context(cfg Config) &Context {
 | 
						|
	mut g := &Context{}
 | 
						|
 | 
						|
	g.user_data = cfg.user_data
 | 
						|
	g.width = cfg.width
 | 
						|
	g.height = cfg.height
 | 
						|
	g.ui_mode = cfg.ui_mode
 | 
						|
	mut sz := gg.size
 | 
						|
	sz.height = g.height
 | 
						|
	sz.width = g.width
 | 
						|
	g.config = cfg
 | 
						|
	if isnil(cfg.user_data) {
 | 
						|
		g.user_data = g
 | 
						|
	}
 | 
						|
	g.window = dom.window()
 | 
						|
	document := dom.document
 | 
						|
	canvas_elem := document.getElementById(cfg.canvas.str) or {
 | 
						|
		panic('gg: cannot get canvas element')
 | 
						|
	}
 | 
						|
	canvas := get_canvas(canvas_elem)
 | 
						|
	g.canvas = canvas
 | 
						|
	g.context = get_context(g.canvas)
 | 
						|
 | 
						|
	mouse_down_event_handler := fn [mut g] (event JS.Event) {
 | 
						|
		match event {
 | 
						|
			JS.MouseEvent {
 | 
						|
				e := g.handle_mouse_event(event, .mouse_down)
 | 
						|
				if !isnil(g.config.event_fn) {
 | 
						|
					f := g.config.event_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
				if !isnil(g.config.click_fn) {
 | 
						|
					f := g.config.click_fn
 | 
						|
					f(e.mouse_x, e.mouse_y, e.mouse_button, g.config.user_data)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	mouse_up_event_handler := fn [mut g] (event JS.Event) {
 | 
						|
		match event {
 | 
						|
			JS.MouseEvent {
 | 
						|
				e := g.handle_mouse_event(event, .mouse_up)
 | 
						|
				if !isnil(g.config.event_fn) {
 | 
						|
					f := g.config.event_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
				if !isnil(g.config.unclick_fn) {
 | 
						|
					f := g.config.unclick_fn
 | 
						|
					f(e.mouse_x, e.mouse_y, e.mouse_button, g.config.user_data)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	mouse_move_event_handler := fn [mut g] (event JS.Event) {
 | 
						|
		match event {
 | 
						|
			JS.MouseEvent {
 | 
						|
				e := g.handle_mouse_event(event, .mouse_move)
 | 
						|
				if !isnil(g.config.event_fn) {
 | 
						|
					f := g.config.event_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
				if !isnil(g.config.move_fn) {
 | 
						|
					f := g.config.move_fn
 | 
						|
					f(e.mouse_x, e.mouse_y, g.config.user_data)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	mouse_leave_event_handler := fn [mut g] (event JS.Event) {
 | 
						|
		match event {
 | 
						|
			JS.MouseEvent {
 | 
						|
				e := g.handle_mouse_event(event, .mouse_leave)
 | 
						|
				if !isnil(g.config.event_fn) {
 | 
						|
					f := g.config.event_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
				if !isnil(g.config.leave_fn) {
 | 
						|
					f := g.config.leave_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	mouse_enter_event_handler := fn [mut g] (event JS.Event) {
 | 
						|
		match event {
 | 
						|
			JS.MouseEvent {
 | 
						|
				e := g.handle_mouse_event(event, .mouse_enter)
 | 
						|
				if !isnil(g.config.event_fn) {
 | 
						|
					f := g.config.event_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
				if !isnil(g.config.enter_fn) {
 | 
						|
					f := g.config.enter_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	keydown_event_handler := fn [mut g] (event JS.Event) {
 | 
						|
		println('keyboard')
 | 
						|
		match event {
 | 
						|
			JS.KeyboardEvent {
 | 
						|
				e := g.handle_keyboard_event(event, .key_down)
 | 
						|
 | 
						|
				if !isnil(g.config.event_fn) {
 | 
						|
					f := g.config.event_fn
 | 
						|
					f(e, g.config.user_data)
 | 
						|
				}
 | 
						|
				if !isnil(g.config.keydown_fn) {
 | 
						|
					f := g.config.keydown_fn
 | 
						|
					// todo: modifiers
 | 
						|
					f(e.key_code, .super, g.config.user_data)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	g.canvas.addEventListener('mousedown'.str, mouse_down_event_handler, JS.EventListenerOptions{})
 | 
						|
	dom.window().addEventListener('mouseup'.str, mouse_up_event_handler, JS.EventListenerOptions{})
 | 
						|
	g.canvas.addEventListener('mousemove'.str, mouse_move_event_handler, JS.EventListenerOptions{})
 | 
						|
	g.canvas.addEventListener('mouseleave'.str, mouse_leave_event_handler, JS.EventListenerOptions{})
 | 
						|
	g.canvas.addEventListener('mouseenter'.str, mouse_enter_event_handler, JS.EventListenerOptions{})
 | 
						|
	dom.document.addEventListener('keydown'.str, keydown_event_handler, JS.EventListenerOptions{})
 | 
						|
	return g
 | 
						|
}
 | 
						|
 | 
						|
pub fn (mut ctx Context) run() {
 | 
						|
	gg_animation_frame_fn(mut ctx)
 | 
						|
}
 | 
						|
 | 
						|
pub fn (mut ctx Context) begin() {
 | 
						|
	// ctx.context.beginPath()
 | 
						|
}
 | 
						|
 | 
						|
pub fn (mut ctx Context) end() {
 | 
						|
	// ctx.context.closePath()
 | 
						|
}
 | 
						|
 | 
						|
pub fn (mut ctx Context) draw_line(x1 f32, y1 f32, x2 f32, y2 f32, c gx.Color) {
 | 
						|
	ctx.context.beginPath()
 | 
						|
	ctx.context.strokeStyle = c.to_css_string().str
 | 
						|
	ctx.context.moveTo(x1, y1)
 | 
						|
	ctx.context.lineTo(x2, y2)
 | 
						|
	ctx.context.stroke()
 | 
						|
	ctx.context.closePath()
 | 
						|
}
 | 
						|
 | 
						|
pub fn (mut ctx Context) quit() {
 | 
						|
}
 | 
						|
 | 
						|
pub fn (mut ctx Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) {
 | 
						|
	ctx.context.beginPath()
 | 
						|
	ctx.context.fillStyle = c.to_css_string().str
 | 
						|
	ctx.context.fillRect(x, y, w, h)
 | 
						|
	ctx.context.closePath()
 | 
						|
}
 | 
						|
 | 
						|
fn gg_animation_frame_fn(mut g Context) {
 | 
						|
	g.frame++
 | 
						|
	g.context.clearRect(0, 0, g.config.width, g.config.height)
 | 
						|
	// todo(playXE): handle events
 | 
						|
 | 
						|
	if !isnil(g.config.frame_fn) {
 | 
						|
		f := g.config.frame_fn
 | 
						|
		f(g.user_data)
 | 
						|
		g.needs_refresh = false
 | 
						|
	}
 | 
						|
 | 
						|
	g.window.requestAnimationFrame(fn [mut g] (time JS.Number) {
 | 
						|
		gg_animation_frame_fn(mut g)
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
fn (mut g Context) handle_mouse_event(event JS.MouseEvent, typ DOMEventType) Event {
 | 
						|
	mut e := Event{}
 | 
						|
 | 
						|
	e.typ = typ
 | 
						|
	e.frame_count = g.frame
 | 
						|
 | 
						|
	match int(event.button) {
 | 
						|
		0 {
 | 
						|
			e.mouse_button = .left
 | 
						|
		}
 | 
						|
		1 {
 | 
						|
			e.mouse_button = .middle
 | 
						|
		}
 | 
						|
		2 {
 | 
						|
			e.mouse_button = .right
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			e.mouse_button = .invalid
 | 
						|
		}
 | 
						|
	}
 | 
						|
	e.mouse_x = int(event.offsetX)
 | 
						|
	e.mouse_y = int(event.offsetY)
 | 
						|
	e.mouse_dx = int(event.movementX)
 | 
						|
	e.mouse_dy = int(event.movementY)
 | 
						|
	bitplace := int(event.button)
 | 
						|
	g.mbtn_mask |= u8(1 << bitplace)
 | 
						|
	// g.mouse_buttons = MouseButtons(g.mbtn_mask)
 | 
						|
 | 
						|
	g.mouse_pos_x = int(event.offsetX)
 | 
						|
	g.mouse_pos_y = int(event.offsetY)
 | 
						|
	g.mouse_dx = int(event.movementX)
 | 
						|
	g.mouse_dy = int(event.movementY)
 | 
						|
	return e
 | 
						|
}
 | 
						|
 | 
						|
fn (mut g Context) handle_keyboard_event(event JS.KeyboardEvent, typ DOMEventType) Event {
 | 
						|
	mut e := Event{}
 | 
						|
	e.typ = typ
 | 
						|
	e.frame_count = g.frame
 | 
						|
 | 
						|
	match string(event.code) {
 | 
						|
		'Space' {
 | 
						|
			e.key_code = .space
 | 
						|
		}
 | 
						|
		'Minus' {
 | 
						|
			e.key_code = .minus
 | 
						|
		}
 | 
						|
		'Quote' {
 | 
						|
			e.key_code = .apostrophe
 | 
						|
		}
 | 
						|
		'Comma' {
 | 
						|
			e.key_code = .comma
 | 
						|
		}
 | 
						|
		'Period' {
 | 
						|
			e.key_code = .period
 | 
						|
		}
 | 
						|
		'Digit0' {
 | 
						|
			e.key_code = ._0
 | 
						|
		}
 | 
						|
		'Digit1' {
 | 
						|
			e.key_code = ._1
 | 
						|
		}
 | 
						|
		'Digit2' {
 | 
						|
			e.key_code = ._2
 | 
						|
		}
 | 
						|
		'Digit3' {
 | 
						|
			e.key_code = ._3
 | 
						|
		}
 | 
						|
		'Digit4' {
 | 
						|
			e.key_code = ._4
 | 
						|
		}
 | 
						|
		'Digit5' {
 | 
						|
			e.key_code = ._5
 | 
						|
		}
 | 
						|
		'Digit6' {
 | 
						|
			e.key_code = ._6
 | 
						|
		}
 | 
						|
		'Digit7' {
 | 
						|
			e.key_code = ._7
 | 
						|
		}
 | 
						|
		'Digit8' {
 | 
						|
			e.key_code = ._8
 | 
						|
		}
 | 
						|
		'Digit9' {
 | 
						|
			e.key_code = ._9
 | 
						|
		}
 | 
						|
		'Semicolon' {
 | 
						|
			e.key_code = .semicolon
 | 
						|
		}
 | 
						|
		'Equal' {
 | 
						|
			e.key_code = .equal
 | 
						|
		}
 | 
						|
		'KeyA' {
 | 
						|
			e.key_code = .a
 | 
						|
		}
 | 
						|
		'KeyB' {
 | 
						|
			e.key_code = .b
 | 
						|
		}
 | 
						|
		'KeyC' {
 | 
						|
			e.key_code = .c
 | 
						|
		}
 | 
						|
		'KeyD' {
 | 
						|
			e.key_code = .d
 | 
						|
		}
 | 
						|
		'KeyE' {
 | 
						|
			e.key_code = .e
 | 
						|
		}
 | 
						|
		'KeyF' {
 | 
						|
			e.key_code = .f
 | 
						|
		}
 | 
						|
		'KeyG' {
 | 
						|
			e.key_code = .g
 | 
						|
		}
 | 
						|
		'KeyH' {
 | 
						|
			e.key_code = .h
 | 
						|
		}
 | 
						|
		'KeyI' {
 | 
						|
			e.key_code = .i
 | 
						|
		}
 | 
						|
		'KeyJ' {
 | 
						|
			e.key_code = .j
 | 
						|
		}
 | 
						|
		'KeyK' {
 | 
						|
			e.key_code = .k
 | 
						|
		}
 | 
						|
		'KeyL' {
 | 
						|
			e.key_code = .l
 | 
						|
		}
 | 
						|
		'KeyM' {
 | 
						|
			e.key_code = .m
 | 
						|
		}
 | 
						|
		'KeyN' {
 | 
						|
			e.key_code = .n
 | 
						|
		}
 | 
						|
		'KeyO' {
 | 
						|
			e.key_code = .o
 | 
						|
		}
 | 
						|
		'KeyP' {
 | 
						|
			e.key_code = .p
 | 
						|
		}
 | 
						|
		'KeyQ' {
 | 
						|
			e.key_code = .q
 | 
						|
		}
 | 
						|
		'KeyR' {
 | 
						|
			e.key_code = .r
 | 
						|
		}
 | 
						|
		'KeyS' {
 | 
						|
			e.key_code = .s
 | 
						|
		}
 | 
						|
		'KeyT' {
 | 
						|
			e.key_code = .t
 | 
						|
		}
 | 
						|
		'KeyU' {
 | 
						|
			e.key_code = .u
 | 
						|
		}
 | 
						|
		'KeyV' {
 | 
						|
			e.key_code = .v
 | 
						|
		}
 | 
						|
		'KeyW' {
 | 
						|
			e.key_code = .w
 | 
						|
		}
 | 
						|
		'KeyX' {
 | 
						|
			e.key_code = .x
 | 
						|
		}
 | 
						|
		'KeyY' {
 | 
						|
			e.key_code = .y
 | 
						|
		}
 | 
						|
		'KeyZ' {
 | 
						|
			e.key_code = .z
 | 
						|
		}
 | 
						|
		'BracketLeft' {
 | 
						|
			e.key_code = .left_bracket
 | 
						|
		}
 | 
						|
		'BracketRight' {
 | 
						|
			e.key_code = .right_bracket
 | 
						|
		}
 | 
						|
		'Backslash' {
 | 
						|
			e.key_code = .backslash
 | 
						|
		}
 | 
						|
		'Backquote' {
 | 
						|
			e.key_code = .grave_accent
 | 
						|
		}
 | 
						|
		'Escape' {
 | 
						|
			e.key_code = .escape
 | 
						|
		}
 | 
						|
		'Enter' {
 | 
						|
			e.key_code = .enter
 | 
						|
		}
 | 
						|
		'Tab' {
 | 
						|
			e.key_code = .tab
 | 
						|
		}
 | 
						|
		'Backspace' {
 | 
						|
			e.key_code = .backspace
 | 
						|
		}
 | 
						|
		'Insert' {
 | 
						|
			e.key_code = .insert
 | 
						|
		}
 | 
						|
		'Delete' {
 | 
						|
			e.key_code = .delete
 | 
						|
		}
 | 
						|
		'ArrowRight' {
 | 
						|
			e.key_code = .right
 | 
						|
		}
 | 
						|
		'ArrowLeft' {
 | 
						|
			e.key_code = .left
 | 
						|
		}
 | 
						|
		'ArrowUp' {
 | 
						|
			e.key_code = .up
 | 
						|
		}
 | 
						|
		'ArrowDown' {
 | 
						|
			e.key_code = .down
 | 
						|
		}
 | 
						|
		'PageUp' {
 | 
						|
			e.key_code = .page_up
 | 
						|
		}
 | 
						|
		'PageDown' {
 | 
						|
			e.key_code = .page_down
 | 
						|
		}
 | 
						|
		'Home' {
 | 
						|
			e.key_code = .home
 | 
						|
		}
 | 
						|
		'End' {
 | 
						|
			e.key_code = .end
 | 
						|
		}
 | 
						|
		'CapsLock' {
 | 
						|
			e.key_code = .caps_lock
 | 
						|
		}
 | 
						|
		'ScrollLock' {
 | 
						|
			e.key_code = .scroll_lock
 | 
						|
		}
 | 
						|
		'NumLock' {
 | 
						|
			e.key_code = .num_lock
 | 
						|
		}
 | 
						|
		'PrintScreen' {
 | 
						|
			e.key_code = .print_screen
 | 
						|
		}
 | 
						|
		'Pause' {
 | 
						|
			e.key_code = .pause
 | 
						|
		}
 | 
						|
		'ShiftLeft' {
 | 
						|
			e.key_code = .left_shift
 | 
						|
		}
 | 
						|
		'ShiftRight' {
 | 
						|
			e.key_code = .right_shift
 | 
						|
		}
 | 
						|
		'AltLeft' {
 | 
						|
			e.key_code = .left_alt
 | 
						|
		}
 | 
						|
		'AltRight' {
 | 
						|
			e.key_code = .right_alt
 | 
						|
		}
 | 
						|
		'ControlLeft' {
 | 
						|
			e.key_code = .left_control
 | 
						|
		}
 | 
						|
		'ControlRight' {
 | 
						|
			e.key_code = .right_control
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			panic('todo: more keycodes (${string(event.code)})')
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return e
 | 
						|
}
 |