123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- #+build js wasm32, js wasm64p32
- package wasm_js_interface
- foreign import dom_lib "odin_dom"
- Event_Kind :: enum u32 {
- Invalid,
- Load,
- Unload,
- Error,
- Resize,
- Visibility_Change,
- Fullscreen_Change,
- Fullscreen_Error,
- Click,
- Double_Click,
- Mouse_Move,
- Mouse_Over,
- Mouse_Out,
- Mouse_Up,
- Mouse_Down,
- Key_Up,
- Key_Down,
- Key_Press,
- Scroll,
- Wheel,
- Focus,
- Focus_In,
- Focus_Out,
- Submit,
- Blur,
- Change,
- Hash_Change,
- Select,
- Animation_Start,
- Animation_End,
- Animation_Iteration,
- Animation_Cancel,
- Copy,
- Cut,
- Paste,
- // Drag,
- // Drag_Start,
- // Drag_End,
- // Drag_Enter,
- // Drag_Leave,
- // Drag_Over,
- // Drop,
- Pointer_Cancel,
- Pointer_Down,
- Pointer_Enter,
- Pointer_Leave,
- Pointer_Move,
- Pointer_Over,
- Pointer_Up,
- Got_Pointer_Capture,
- Lost_Pointer_Capture,
- Pointer_Lock_Change,
- Pointer_Lock_Error,
- Selection_Change,
- Selection_Start,
- Touch_Cancel,
- Touch_End,
- Touch_Move,
- Touch_Start,
- Transition_Start,
- Transition_End,
- Transition_Run,
- Transition_Cancel,
- Context_Menu,
- Gamepad_Connected,
- Gamepad_Disconnected,
- Custom,
- }
- event_kind_string := [Event_Kind]string{
- .Invalid = "",
- .Load = "load",
- .Unload = "unload",
- .Error = "error",
- .Resize = "resize",
- .Visibility_Change = "visibilitychange",
- .Fullscreen_Change = "fullscreenchange",
- .Fullscreen_Error = "fullscreenerror",
- .Click = "click",
- .Double_Click = "dblclick",
- .Mouse_Move = "mousemove",
- .Mouse_Over = "mouseover",
- .Mouse_Out = "mouseout",
- .Mouse_Up = "mouseup",
- .Mouse_Down = "mousedown",
- .Key_Up = "keyup",
- .Key_Down = "keydown",
- .Key_Press = "keypress",
- .Scroll = "scroll",
- .Wheel = "wheel",
- .Focus = "focus",
- .Focus_In = "focusin",
- .Focus_Out = "focusout",
- .Submit = "submit",
- .Blur = "blur",
- .Change = "change",
- .Hash_Change = "hashchange",
- .Select = "select",
- .Animation_Start = "animationstart",
- .Animation_End = "animationend",
- .Animation_Iteration = "animationiteration",
- .Animation_Cancel = "animationcancel",
- .Copy = "copy",
- .Cut = "cut",
- .Paste = "paste",
- // .Drag, = "drag",
- // .Drag_Start, = "dragstart",
- // .Drag_End, = "dragend",
- // .Drag_Enter, = "dragenter",
- // .Drag_Leave, = "dragleave",
- // .Drag_Over, = "dragover",
- // .Drop, = "drop",
- .Pointer_Cancel = "pointercancel",
- .Pointer_Down = "pointerdown",
- .Pointer_Enter = "pointerenter",
- .Pointer_Leave = "pointerleave",
- .Pointer_Move = "pointermove",
- .Pointer_Over = "pointerover",
- .Pointer_Up = "pointerup",
- .Got_Pointer_Capture = "gotpointercapture",
- .Lost_Pointer_Capture = "lostpointercapture",
- .Pointer_Lock_Change = "pointerlockchange",
- .Pointer_Lock_Error = "pointerlockerror",
- .Selection_Change = "selectionchange",
- .Selection_Start = "selectionstart",
- .Transition_Start = "transitionstart",
- .Transition_End = "transitionend",
- .Transition_Run = "transitionrun",
- .Transition_Cancel = "transitioncancel",
- .Touch_Cancel = "touchcancel",
- .Touch_End = "touchend",
- .Touch_Move = "touchmove",
- .Touch_Start = "touchstart",
- .Context_Menu = "contextmenu",
- .Gamepad_Connected = "gamepadconnected",
- .Gamepad_Disconnected = "gamepaddisconnected",
- .Custom = "?custom?",
- }
- Delta_Mode :: enum u32 {
- Pixel = 0,
- Line = 1,
- Page = 2,
- }
- Key_Location :: enum u8 {
- Standard = 0,
- Left = 1,
- Right = 2,
- Numpad = 3,
- }
- KEYBOARD_MAX_KEY_SIZE :: 32
- KEYBOARD_MAX_CODE_SIZE :: 32
- GAMEPAD_MAX_ID_SIZE :: 96
- GAMEPAD_MAX_MAPPING_SIZE :: 64
- GAMEPAD_MAX_BUTTONS :: 64
- GAMEPAD_MAX_AXES :: 16
- Event_Target_Kind :: enum u32 {
- Element = 0,
- Document = 1,
- Window = 2,
- }
- Event_Phase :: enum u8 {
- None = 0,
- Capturing_Phase = 1,
- At_Target = 2,
- Bubbling_Phase = 3,
- }
- Event_Option :: enum u8 {
- Bubbles = 0,
- Cancelable = 1,
- Composed = 2,
- }
- Event_Options :: distinct bit_set[Event_Option; u8]
- Gamepad_Button :: struct {
- value: f64,
- pressed: bool,
- touched: bool,
- }
- Gamepad_State :: struct {
- id: string,
- mapping: string,
- index: int,
- connected: bool,
- timestamp: f64,
- button_count: int,
- axis_count: int,
- buttons: [GAMEPAD_MAX_BUTTONS]Gamepad_Button `fmt:"v,button_count"`,
- axes: [GAMEPAD_MAX_AXES]f64 `fmt:"v,axes_count"`,
- _id_len: int `fmt:"-"`,
- _mapping_len: int `fmt:"-"`,
- _id_buf: [GAMEPAD_MAX_ID_SIZE]byte `fmt:"-"`,
- _mapping_buf: [GAMEPAD_MAX_MAPPING_SIZE]byte `fmt:"-"`,
- }
- Pointer_Type :: enum u8 {
- Mouse,
- Pen,
- Touch,
- }
- Event :: struct {
- kind: Event_Kind,
- target_kind: Event_Target_Kind,
- current_target_kind: Event_Target_Kind,
- id: string,
- timestamp: f64,
- phase: Event_Phase,
- options: Event_Options,
- is_composing: bool,
- is_trusted: bool,
- using data: struct #raw_union #align(8) {
- scroll: struct {
- delta: [2]f64,
- },
- visibility_change: struct {
- is_visible: bool,
- },
- wheel: struct {
- delta: [3]f64,
- delta_mode: Delta_Mode,
- },
- key: struct {
- key: string,
- code: string,
- location: Key_Location,
- ctrl: bool,
- shift: bool,
- alt: bool,
- meta: bool,
- repeat: bool,
- char: rune,
- _key_len: int `fmt:"-"`,
- _code_len: int `fmt:"-"`,
- _key_buf: [KEYBOARD_MAX_KEY_SIZE]byte `fmt:"-"`,
- _code_buf: [KEYBOARD_MAX_KEY_SIZE]byte `fmt:"-"`,
- },
- mouse: struct {
- screen: [2]i64,
- client: [2]i64,
- offset: [2]i64,
- page: [2]i64,
- movement: [2]i64,
- ctrl: bool,
- shift: bool,
- alt: bool,
- meta: bool,
- button: i16,
- buttons: bit_set[0..<16; u16],
- pointer: struct {
- altitude_angle: f64,
- azimuth_angle: f64,
- persistent_device_id: int,
- pointer_id: int,
- width: int,
- height: int,
- pressure: f64,
- tangential_pressure: f64,
- tilt: [2]f64,
- twist: f64,
- pointer_type: Pointer_Type,
- is_primary: bool,
- },
- },
- gamepad: Gamepad_State,
- },
- user_data: rawptr,
- callback: proc(e: Event),
- }
- @(default_calling_convention="contextless")
- foreign dom_lib {
- event_stop_propagation :: proc() ---
- event_stop_immediate_propagation :: proc() ---
- event_prevent_default :: proc() ---
- dispatch_custom_event :: proc(id: string, name: string, options := Event_Options{}) -> bool ---
- }
- add_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="add_event_listener")
- _add_event_listener :: proc(id: string, name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- // TODO: Pointer_Lock_Change etc related stuff for all different browsers
- return _add_event_listener(id, event_kind_string[kind], kind, user_data, callback, use_capture)
- }
- remove_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="remove_event_listener")
- _remove_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- return _remove_event_listener(id, event_kind_string[kind], user_data, callback, use_capture)
- }
- add_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="add_window_event_listener")
- _add_window_event_listener :: proc(name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- return _add_window_event_listener(event_kind_string[kind], kind, user_data, callback, use_capture)
- }
- remove_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="remove_window_event_listener")
- _remove_window_event_listener :: proc(name: string, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- return _remove_window_event_listener(event_kind_string[kind], user_data, callback, use_capture)
- }
- add_document_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="add_document_event_listener")
- _add_document_event_listener :: proc(name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- return _add_document_event_listener(event_kind_string[kind], kind, user_data, callback, use_capture)
- }
- remove_document_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="remove_document_event_listener")
- _remove_document_event_listener :: proc(name: string, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- return _remove_document_event_listener(event_kind_string[kind], user_data, callback, use_capture)
- }
- remove_event_listener_from_event :: proc(e: Event) -> bool {
- from_use_capture_false: bool
- from_use_capture_true: bool
- if e.id == "" {
- from_use_capture_false = remove_window_event_listener(e.kind, e.user_data, e.callback, false)
- from_use_capture_true = remove_window_event_listener(e.kind, e.user_data, e.callback, true)
- from_use_capture_false |= remove_document_event_listener(e.kind, e.user_data, e.callback, false)
- from_use_capture_true |= remove_document_event_listener(e.kind, e.user_data, e.callback, true)
- } else {
- from_use_capture_false = remove_event_listener(e.id, e.kind, e.user_data, e.callback, false)
- from_use_capture_true = remove_event_listener(e.id, e.kind, e.user_data, e.callback, true)
- }
- return from_use_capture_false || from_use_capture_true
- }
- add_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="add_event_listener")
- _add_event_listener :: proc(id: string, name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- return _add_event_listener(id, name, .Custom, user_data, callback, use_capture)
- }
- remove_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="remove_event_listener")
- _remove_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
- }
- return _remove_event_listener(id, name, user_data, callback, use_capture)
- }
- get_gamepad_state :: proc "contextless" (index: int, s: ^Gamepad_State) -> bool {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- @(link_name="get_gamepad_state")
- _get_gamepad_state :: proc(index: int, s: ^Gamepad_State) -> bool ---
- }
- if s == nil {
- return false
- }
- if !_get_gamepad_state(index, s) {
- return false
- }
- s.id = string(s._id_buf[:s._id_len])
- s.mapping = string(s._mapping_buf[:s._mapping_len])
- return true
- }
- @(export, link_name="odin_dom_do_event_callback")
- do_event_callback :: proc(user_data: rawptr, callback: proc(e: Event)) {
- @(default_calling_convention="contextless")
- foreign dom_lib {
- init_event_raw :: proc(e: ^Event) ---
- }
- if callback != nil {
- event := Event{
- user_data = user_data,
- callback = callback,
- }
- init_event_raw(&event)
- #partial switch event.kind {
- case .Key_Up, .Key_Down, .Key_Press:
- event.key.key = string(event.key._key_buf[:event.key._key_len])
- event.key.code = string(event.key._code_buf[:event.key._code_len])
- case .Gamepad_Connected, .Gamepad_Disconnected:
- event.gamepad.id = string(event.gamepad._id_buf[:event.gamepad._id_len])
- event.gamepad.mapping = string(event.gamepad._mapping_buf[:event.gamepad._mapping_len])
- }
- callback(event)
- }
- }
|