Keyboard signals and foldp in Elm -
i'm trying make text field submits input pressing enter , cleared escape.
import graphics.element exposing (flow, down, show) import signal exposing ((<~), (~)) import graphics.input.field exposing (nocontent, defaultstyle, field) import string import keyboard main = signal.map view (signal.foldp step init signals) signals = (,,) <~ box.signal ~ signal.sampleon keyboard.enter box.signal ~ escape escape = keyboard.isdown 27 box = signal.mailbox nocontent init = (nocontent, nocontent, false) view (text, query, clear) = flow down [ field defaultstyle (signal.message box.address) "enter text" text , show (string.words query.string) ] step (text, query, clear) _ = case clear of false -> (text, query, clear) true -> (nocontent, nocontent, clear) this produces empty field while holding escape , reverts whatever entered when escape released.
trying understand why case lead me smaller example:
import graphics.element exposing (show) import signal import char import string import keyboard main = signal.map show input input = signal.foldp step "" (signal.map2 (,) keyboard.presses escapedown) escapedown = keyboard.isdown 27 step (keycode, esc) string = case esc of true -> "" false -> string ++ keytostring keycode keytostring = string.fromchar << char.fromcode the accumulated string of characters emptied on pressing escape releasing results in string of single (last entered) character.
from understand, keyboard.isdown signal triggered while holding , on key release. how can clear field persistently?
the reason see behaviour
when create signal of pairs (signal (keycode,bool)) out of 2 signals (signal keycode/signal bool), signal of pairs update every time of of signals update. value of signal.map2 (,) keyboard.presses escapedown on time might be:
(0,false), (97,false), (98,false), (98,true), (98,false) ^ ^ press 'a' ^ press 'b' ^ ^ release escape program start press escape when press escape, pair of values changes , foldp updates empty string. when release escape pair of values changes again, foldp updates again, finds false value, therefore appends last character pressed empty string.
solution
in case you're interested in event when escape pressed, not when isdown. instead of creating pair of signals, in case better merge signals. need of same type. here's example:
import graphics.element exposing (show) import signal exposing ((<~)) import char import string import keyboard type input = keypress keyboard.keycode | escapepress main = signal.map show output presses = keypress <~ signal.filter ((/=) 27) 0 keyboard.presses escapepress = escapepress <~ escapedown input = signal.merge escapepress presses output = signal.foldp step "" input escapedown = keyboard.isdown 27 step input string = case input of escapepress -> "" keypress keycode -> string ++ keytostring keycode keytostring = string.fromchar << char.fromcode with union type input, represent different inputs program. presses wrapped in keypress constructor of union type. escape button represented other constructor escapepress. have 2 signals of same type, can merge. in step function pattern match on constructors of input, , handle familiar cases.
note i'm filtering keyboard.presses signal don't keypress event pressing down, holding down or letting go of escape key.
Comments
Post a Comment