107 lines
4.4 KiB
Plaintext
107 lines
4.4 KiB
Plaintext
;;;; raylib [core] example - input gestures
|
|
;;;;
|
|
;;;; examples/core/core_input_gestures.c. Needed `fade`, now bound.
|
|
;;;;
|
|
;;;; The C keeps `char gestureStrings[20][32]` and TextCopy's a name into the
|
|
;;;; next slot. Flan has no mutable character buffer and no way to copy into
|
|
;;;; one, but it does not need either: the names are compile-time literals, so
|
|
;;;; the log is a `[20 string]` and a slot holds the literal itself. That is
|
|
;;;; strictly better than the C — no truncation at 32 bytes, no copy — and it
|
|
;;;; is only possible because every string that ever goes into the log is
|
|
;;;; known at compile time. A log of strings the program had BUILT could not be
|
|
;;;; written at all.
|
|
;;;;
|
|
;;;; The C's `switch (currentGesture)` over the ten gesture values is a `cond`
|
|
;;;; of keyword equalities. `get-gesture-detected` answers an `rl/Gesture` and
|
|
;;;; `(= g :gesture-tap)` compares against a member by name, checked at
|
|
;;;; compile time — so a typo here is an error and the C's `default: break`
|
|
;;;; has nothing to catch.
|
|
;;;;
|
|
;;;; A slot that has not been written yet holds a zero-length string, because a
|
|
;;;; `once` with no initialiser is all-bytes-zero and a string is ptr+len —
|
|
;;;; a null pointer with a length of 0. draw-text draws nothing for it. That is
|
|
;;;; the C's `{ "" }` initialiser arriving by a different route, and it is why
|
|
;;;; resetting the log below only has to reset the counter.
|
|
|
|
import rl "vendor:raylib"
|
|
|
|
const screen-width = 800
|
|
const screen-height = 450
|
|
|
|
const max-gesture-strings = 20
|
|
|
|
once gesture-log: [max-gesture-strings str]
|
|
once gestures-count: i32
|
|
once current-gesture: rl/Gesture
|
|
once last-gesture: rl/Gesture
|
|
|
|
;; The C's switch, as a function. `:else` is its `default:` — an unnamed
|
|
;; gesture logs the empty string, which draws nothing, which is what falling
|
|
;; through the C's switch without a TextCopy leaves in the slot.
|
|
fn gesture-name(g: rl/Gesture) -> str
|
|
if g == :gesture-tap
|
|
"GESTURE TAP"
|
|
elif g == :gesture-double-tap
|
|
"GESTURE DOUBLETAP"
|
|
elif g == :gesture-hold
|
|
"GESTURE HOLD"
|
|
elif g == :gesture-drag
|
|
"GESTURE DRAG"
|
|
elif g == :gesture-swipe-right
|
|
"GESTURE SWIPE RIGHT"
|
|
elif g == :gesture-swipe-left
|
|
"GESTURE SWIPE LEFT"
|
|
elif g == :gesture-swipe-up
|
|
"GESTURE SWIPE UP"
|
|
elif g == :gesture-swipe-down
|
|
"GESTURE SWIPE DOWN"
|
|
elif g == :gesture-pinch-in
|
|
"GESTURE PINCH IN"
|
|
elif g == :gesture-pinch-out
|
|
"GESTURE PINCH OUT"
|
|
else
|
|
""
|
|
|
|
fn main() -> ()
|
|
rl/init-window(screen-width, screen-height,
|
|
"raylib [core] example - input gestures")
|
|
defer rl/close-window()
|
|
rl/set-target-fps(60)
|
|
let touch-area = rl/Rectangle{.x 220.0, .y 10.0, .width f32(screen-width) - 230.0, .height f32(screen-height) - 20.0}
|
|
until rl/window-should-close()
|
|
;; Update
|
|
last-gesture = current-gesture
|
|
current-gesture = rl/get-gesture-detected()
|
|
let touch = rl/get-touch-position(0)
|
|
if rl/check-collision-point-rec(touch, touch-area) and not current-gesture == :gesture-none and not current-gesture == last-gesture
|
|
gesture-log[gestures-count] = gesture-name(current-gesture)
|
|
gestures-count += 1
|
|
;; Full: start over. The stale slots below the counter are never
|
|
;; drawn, so they do not have to be cleared the way the C clears
|
|
;; them — the loop below is bounded by gestures-count.
|
|
if gestures-count >= max-gesture-strings
|
|
gestures-count = 0
|
|
;; Draw
|
|
rl/with-drawing:
|
|
rl/clear-background(rl/raywhite)
|
|
rl/draw-rectangle-rec(touch-area, rl/gray)
|
|
rl/draw-rectangle(225, 15, screen-width - 240, screen-height - 30,
|
|
rl/raywhite)
|
|
rl/draw-text("GESTURES TEST AREA", screen-width - 270, screen-height - 40,
|
|
20, rl/fade(rl/gray, 0.5))
|
|
for i in range(gestures-count)
|
|
if 0 == i % 2
|
|
rl/draw-rectangle(10, 30 + 20 * i, 200, 20,
|
|
rl/fade(rl/lightgray, 0.5))
|
|
else
|
|
rl/draw-rectangle(10, 30 + 20 * i, 200, 20,
|
|
rl/fade(rl/lightgray, 0.3))
|
|
;; The newest entry in maroon and the rest in dark grey, as the C
|
|
;; has it.
|
|
rl/draw-text(gesture-log[i], 35, 36 + 20 * i, 10,
|
|
if i < gestures-count - 1 then rl/darkgray else rl/maroon)
|
|
rl/draw-rectangle-lines(10, 29, 200, screen-height - 50, rl/gray)
|
|
rl/draw-text("DETECTED GESTURES", 50, 15, 10, rl/gray)
|
|
unless(current-gesture == :gesture-none):
|
|
rl/draw-circle-v(touch, 30.0, rl/maroon)
|