Add proc to show/hide on-screen keyboard and character callbacks (except ios).

* Add `myouSetKeyboardVisible(bool)` and export it.
* Add `screen.char_callbacks` to receive platform character events.
* Remove duplicate code for mouse emulation with touch (commited by mistake).
This commit is contained in:
Alberto Torres 2024-08-28 23:57:29 +02:00
parent 6e60d806e7
commit 6636b5e595
5 changed files with 27 additions and 77 deletions

View file

@ -89,9 +89,11 @@ export ubo
export util
export vmath except Quat
when defined(android):
import platform/platform
when defined(android):
export platform.myouAndroidGetActivity
export platform.myouAndroidGetJniEnv
export platform.myouAndroidGetInternalDataPath
export platform.myouAndroidGetExternalDataPath
export platform.myouSetKeyboardVisible

View file

@ -162,3 +162,7 @@ proc myouOnTouch(touch: int32, ending: char, x, y: float32) {.exportc,cdecl.} =
proc platform_switch_screen*(screen: Screen): bool {.inline.} =
discard
proc myouSetKeyboardVisible*(show: bool) =
assert false, "TODO: myouSetKeyboardVisible in generic"

View file

@ -42,6 +42,7 @@ import std/math
import std/sequtils
import std/strformat
import std/strutils
import std/unicode
import ./gl
import ../screen
import ../util
@ -106,8 +107,8 @@ proc glfmMain(w: Window) {.cdecl,exportc,noreturn.} =
proc make_window*(width, height: int32, title: string): Window =
if window == nil:
return
window.glfmSetKeyFunc proc(display, keyCode, action, mods: auto): auto {.cdecl.} =
# dump (cast[KeyCode](keyCode), keyCode.int, action, mods)
window.glfmSetKeyFunc proc(display: ptr GLFMDisplay; keyCode: GLFMKey;
action: GLFMKeyAction; mods: cint): bool {.cdecl.} =
let key = cast[KeyCode](keyCode)
let shiftKey = (mods and 1).bool
let ctrlKey = (mods and 2).bool
@ -121,6 +122,11 @@ proc make_window*(width, height: int32, title: string): Window =
key: key,
))
return true
window.glfmSetCharFunc proc(display: ptr GLFMDisplay; utf8: cstring; modifiers: cint) {.cdecl.} =
let codepoint = cast[uint32](($utf8).runeAt(0))
for cb in display.screen.char_callbacks:
cb(codepoint)
window.glfmSetTouchFunc proc (display: ptr GLFMDisplay; touch: cint; phase: GLFMTouchPhase;
x: cdouble; y: cdouble): bool {.cdecl.} =
let screen = window.screen
@ -166,77 +172,6 @@ proc make_window*(width, height: int32, title: string): Window =
screen.last_buttons = screen.last_buttons and not (1'i8 shl btn)
screen.last_x = x
screen.last_y = y
# template send_move(x, y: untyped) =
# let buttons = screen.last_buttons
# let left = (buttons and 1).bool
# let middle = (buttons and 2).bool
# let right = (buttons and 4).bool
# let position = vec2(x,y)
# let movement = vec2(x-screen.last_x, y-screen.last_y)
# for cb in screen.mouse_move_callbacks:
# cb(MouseMoveEvent(
# left: left, middle: middle, right: right,
# # shiftKey: shiftKey, ctrlKey: ctrlKey, altKey: altKey, metaKey: metaKey,
# position: position, movement: movement,
# ))
# screen.last_x = x
# screen.last_y = y
# template send_btn(pressed1, btn, x, y: untyped) =
# for cb in window.screen.mouse_button_callbacks:
# cb(MouseButtonEvent(
# pressed: pressed1,
# button: cast[MouseButton](btn),
# position: vec2(x,y)
# ))
# if pressed1:
# screen.last_buttons = screen.last_buttons or (1'i8 shl btn)
# else:
# screen.last_buttons = screen.last_buttons and not (1'i8 shl btn)
# screen.last_x = x
# screen.last_y = y
# template swap_1_2(count: untyped): untyped =
# case count:
# of 1: 2
# of 2: 1
# else: count
# if screen.is_touch:
# # mouse emulation
# if phase in [GLFMTouchPhaseMoved, GLFMTouchPhaseHover]:
# let last = screen.touches[0]
# if last[0] == touch:
# let dx = x - last[1]
# let dy = y - last[2]
# screen.touches[0][1] = x
# screen.touches[0][2] = y
# send_move(screen.last_x + dx, screen.last_y + dy)
# elif phase == GLFMTouchPhaseBegan:
# let count = screen.touches.len
# screen.touches.add (touch.int32, x.float, y.float)
# # in glfm buttons 1 and 2 are swapped so mouse emulation
# # through number of touches behave as we expect (no swap_1_2 here)
# let button = count
# if screen.last_buttons == 0:
# send_btn(true, button, x, y)
# else:
# let previous = screen.last_buttons.countTrailingZeroBits
# if previous < count:
# send_btn(true, button, screen.last_x, screen.last_y)
# send_btn(false, previous, screen.last_x, screen.last_y)
# else:
# screen.touches.keepItIf it[0] != touch
# if screen.touches.len == 0:
# let previous = screen.last_buttons.countTrailingZeroBits
# send_btn(false, previous, x, y)
# else:
# if phase in [GLFMTouchPhaseMoved, GLFMTouchPhaseHover]:
# send_move(x,y)
# else:
# let pressed = phase == GLFMTouchPhaseBegan
# # in glfm buttons 1 and 2 are swapped compared to glfw
# # (but they match DOM)
# send_btn(pressed, touch.swap_1_2, x, y)
return true
window.glfmSetAppFocusFunc proc(window: Window, focused: bool) {.cdecl.} =
@ -369,5 +304,5 @@ proc myouAndroidGetExternalDataPath*(): string =
let activity = cast[ptr array[6, cstring]](window.glfmAndroidGetActivity())
return $activity[5]
proc myouSetKeyboardVisible*(show: bool) =
window.glfmSetKeyboardVisible(show)

View file

@ -88,6 +88,10 @@ proc make_window*(width, height: int32, title: string): Window =
for cb in window.screen.key_callbacks:
cb(e)
)
discard glfw.setCharCallback(window, proc(window: Window, codepoint: uint32) {.cdecl.} =
for cb in window.screen.char_callbacks:
cb(codepoint)
)
discard glfw.setCursorPosCallback(window, proc(window: Window, x, y: float) {.cdecl.} =
# TODO: when a mouse button is pressed do we need to poll the position
# with glfw.getCursorPos until released? not needed on linux
@ -232,3 +236,7 @@ proc start_platform_main_loop*(engine: MyouEngine, main_loop: proc(self: MyouEng
proc myouAndroidGetActivity*(): pointer =
assert false, "Not using Android"
proc myouSetKeyboardVisible*(show: bool) =
discard

View file

@ -789,6 +789,7 @@ type
last_x*, last_y*: float ## private
last_buttons*, last_mods*: int8 ## private
key_callbacks*: seq[proc(event: KeyEvent)] ## private
char_callbacks*: seq[proc(codepoint: uint32)] ## private
mouse_move_callbacks*: seq[proc(event: MouseMoveEvent)] ## private
mouse_button_callbacks*: seq[proc(event: MouseButtonEvent)] ## private
mouse_wheel_callbacks*: seq[proc(event: MouseWheelEvent)] ## private