gg: add event handling for mouse down/up and mouse leave/out on VJS (#12917)
parent
cc2fcb52d6
commit
ade14491d4
|
@ -92,8 +92,10 @@ pub fn isnil(val voidptr) bool {
|
|||
res := false
|
||||
// This one is kinda weird. In C and native backend we can cast booleans and integers to pointers
|
||||
// so we just check *for* all possible NULL-like values here.
|
||||
#val = val.valueOf()
|
||||
#res.val = val === null || val === undefined || val === false || val === 0 || val === BigInt(0)
|
||||
#if (typeof val == 'function') { res.val = false; } else {
|
||||
#val = val instanceof voidptr ? val.valueOf().val : val;
|
||||
#res.val = val === null || val === undefined || val === false || val === 0 || val === BigInt(0) || (val instanceof int ? val.val == 0 : false)
|
||||
#}
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
146
vlib/gg/gg.js.v
146
vlib/gg/gg.js.v
|
@ -40,7 +40,7 @@ pub mut:
|
|||
char_code u32
|
||||
key_repeat bool
|
||||
modifiers u32
|
||||
mouse_button DOMMouseButton
|
||||
mouse_button MouseButton
|
||||
mouse_x f32
|
||||
mouse_y f32
|
||||
mouse_dx f32
|
||||
|
@ -252,7 +252,7 @@ pub:
|
|||
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)
|
||||
context JS.CanvasRenderingContext2D
|
||||
canvas JS.HTMLCanvasElement
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
|
@ -283,12 +283,13 @@ pub mut:
|
|||
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,
|
||||
canvas JS.CanvasRenderingContext2D [noinit]
|
||||
context JS.CanvasRenderingContext2D [noinit]
|
||||
// *before* the current event was different
|
||||
}
|
||||
|
||||
pub fn new_context(cfg Config) &Context {
|
||||
mut g := &Context{}
|
||||
|
||||
g.user_data = cfg.user_data
|
||||
g.width = cfg.width
|
||||
g.height = cfg.height
|
||||
|
@ -298,8 +299,83 @@ pub fn new_context(cfg Config) &Context {
|
|||
g.user_data = g
|
||||
}
|
||||
g.window = dom.window()
|
||||
g.canvas = cfg.context
|
||||
ctx := cfg.canvas.getContext('2d'.str, js_undefined()) or { panic('') }
|
||||
match ctx {
|
||||
JS.CanvasRenderingContext2D {
|
||||
g.context = ctx
|
||||
}
|
||||
else {
|
||||
panic('gg: cannot get 2D context')
|
||||
}
|
||||
}
|
||||
mouse_down_event_handler := fn [mut g] (event JS.Event) {
|
||||
match event {
|
||||
JS.MouseEvent {
|
||||
e := g.handle_mouse_event(event)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
if !isnil(g.config.enter_fn) {
|
||||
f := g.config.enter_fn
|
||||
f(e, g.config.user_data)
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
cfg.canvas.addEventListener('mousedown'.str, mouse_down_event_handler, JS.EventListenerOptions{})
|
||||
dom.window().addEventListener('mouseup'.str, mouse_up_event_handler, JS.EventListenerOptions{})
|
||||
cfg.canvas.addEventListener('mousemove'.str, mouse_move_event_handler, JS.EventListenerOptions{})
|
||||
cfg.canvas.addEventListener('mouseleave'.str, mouse_leave_event_handler, JS.EventListenerOptions{})
|
||||
cfg.canvas.addEventListener('mouseenter'.str, mouse_enter_event_handler, JS.EventListenerOptions{})
|
||||
return g
|
||||
}
|
||||
|
||||
|
@ -308,33 +384,34 @@ pub fn (mut ctx Context) run() {
|
|||
}
|
||||
|
||||
pub fn (mut ctx Context) begin() {
|
||||
// ctx.canvas.beginPath()
|
||||
// ctx.context.beginPath()
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) end() {
|
||||
// ctx.canvas.closePath()
|
||||
// ctx.context.closePath()
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) draw_line(x1 f32, y1 f32, x2 f32, y2 f32, c gx.Color) {
|
||||
ctx.canvas.beginPath()
|
||||
ctx.canvas.strokeStyle = c.to_css_string().str
|
||||
ctx.canvas.moveTo(x1, y1)
|
||||
ctx.canvas.lineTo(x2, y2)
|
||||
ctx.canvas.stroke()
|
||||
ctx.canvas.closePath()
|
||||
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) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) {
|
||||
ctx.canvas.beginPath()
|
||||
ctx.canvas.fillStyle = c.to_css_string().str
|
||||
ctx.canvas.fillRect(x, y, w, h)
|
||||
ctx.canvas.closePath()
|
||||
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.canvas.clearRect(0, 0, g.config.width, g.config.height)
|
||||
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)
|
||||
|
@ -345,3 +422,38 @@ fn gg_animation_frame_fn(mut g Context) {
|
|||
gg_animation_frame_fn(mut g)
|
||||
})
|
||||
}
|
||||
|
||||
fn (mut g Context) handle_mouse_event(event JS.MouseEvent) Event {
|
||||
mut e := Event{}
|
||||
|
||||
e.typ = .mouse_down
|
||||
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 |= byte(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
|
||||
}
|
||||
|
|
|
@ -901,6 +901,14 @@ pub interface JS.MouseEvent {
|
|||
getModifierState(keyArg JS.String) JS.Boolean
|
||||
}
|
||||
|
||||
pub interface JS.WheelEvent {
|
||||
JS.MouseEvent
|
||||
deltaX JS.Number
|
||||
deltaY JS.Number
|
||||
deltaZ JS.Number
|
||||
deltaMode JS.Number
|
||||
}
|
||||
|
||||
pub interface JS.PointerEvent {
|
||||
JS.MouseEvent
|
||||
height JS.Number
|
||||
|
|
Loading…
Reference in New Issue