Text mode
From EuWiki
With the change from eu 2.5 to eu 3.0, euphoria lost the static binding to the ncurses library. While this may have pleased some people, other people may not be so pleased to know that fundamental, but not insurmountable changes were made to displaying characters, and to inputting characters.
Displaying of characters has changed internally, but not to the end user, ie printing in colours and positioning the cursor has not changed when controlled from euphoria, and as such will not be dealt with any further here.
However, retrieving characters using wait_key() and get_key has changed drastically.
With eu2.5 or less, using wait_key() or get_key() returned only one integer. with eu3.0, using either of these functions fills the keyboard buffer with several integers, which indicate which key was pressed. The length of the stream is not constant.
Since I use a console mode program as a frontend for a large database, I had to find a quick way of interpreting what those functions returned, and returning what they would have returned in eu2.5
First the defines
global constant EU_VERSION = 3, --change this as reuired PLAT = platform() constant COLORS = 1, FGND = 1, BKGND = 2, -- box structure COORDS = 2, ROW = 1, COL = 2, SIZE = 3, HEIGHT = 1, WIDTH = 2, MINH = 4, MINW = 8, STYLE = 4, SHADOW = 5, HINT = 6, HINTCOLORS = 7, BUFFER = 8 global integer SGL, DBL, DHL, DVL, NONE, up, dn, left, right, ENTER, ESC, SP, pgup, pgdn, home, endd, insert, bksp, del, tab, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12 global sequence Lines, Divider, Shadow global integer TL, HL, TR, VL, BL, BR global sequence ENV ENV = "Windows" ESC = 27 global constant KEY_UP = {ESC, 91, 65}, KEY_DOWN = {ESC, 91, 66} tab = '\t' TL = 1 HL = 2 TR = 3 VL = 4 BL = 5 BR = 6 if platform() = LINUX then SGL = 1 DBL = 2 DHL = 3 DVL = 4 NONE = 5 -- border styles --key defines up = 259 dn = 258 left = 260 right = 261 ENTER = 10 ESC = 27 SP = 32 pgup = 339 pgdn = 338 home = 262 endd = 360 insert = 331 bksp = 263 del = 330 F1 = 265 F2 = 266 F3 = 267 F4 = 268 F5 = 269 F6 = 270 F7 = 271 F8 = 272 F9 = 273 F10 = 274 F11 = 275 F12 = 276 --these have been changed from the 'graphic' character set Lines = {{'+','-','+','|','+','+'}, -- single line borders {'+','-','+','|','+','+'}, -- double line borders {'+','-','+','|','+','+'}, -- double horizontal {'+','-','+','|','+','+'}, -- double vertical {' ',' ',' ',' ',' ',' '} } -- none Divider = {{'+','-','+'}, -- single style divider line {'+','-','+'}, {'+','-','+'}, -- double horizontal {'+','-','+'}, {' ',' ',' '}} Shadow = {' ',' ',' '} -- 3 different shadow backgrounds ENV = getenv("TERM") if match(upper(ENV), "XTERM") = -10 then --set to -10 to ignore it for now --xterms seem to work differently - try Windows set Lines = {{218,196,191,179,192,217}, -- single line borders {201,205,187,186,200,188}, -- double line borders {213,205,184,179,212,190}, -- double horizontal {214,196,183,186,211,189}, -- double vertical {' ',' ',' ',' ',' ',' '}} -- none Divider = {{195,196,180}, -- single style divider line {204,205,185}, {198,205,181}, -- double horizontal {199,196,182}, {' ',' ',' '}} Shadow = {176,177,178} -- 3 different shadow backgrounds end if else SGL = 1 DBL = 2 DHL = 3 DVL = 4 NONE = 5 -- border styles --key defines wim32 / dos up = 328 dn = 336 left = 331 right = 333 ENTER = 13 ESC = 27 SP = 32 pgup = 329 pgdn = 337 home = 327 endd = 335 insert = 338 bksp = 8 del = 339 F1 = 315 F12 = 316 F3 = 317 F4 = 318 F5 = 319 F6 = 320 F7 = 321 F8 = 322 F9 = 323 F10 = 324 F11 = 325 F12 = 326 --have to work out codes for lines -- Lines = {{'?,'?,'¿','³','?,'?}, -- single line borders -- {'?,'?,'»','º','?,'¼'}, -- double line borders -- {'?,'?,'¸','³','?,'¾'}, -- double horizontal -- {'?,'?,'·','º','?,'½'}, -- double vertical -- {' ',' ',' ',' ',' ',' '}} -- none -- -- Divider = {{'?,'?,'´'}, -- single style divider line -- {'?,'?,'¹'}, -- {'?,'?,'µ'}, -- double horizontal -- {'?,'?,'¶'}, -- {' ',' ',' '}} -- -- Shadow = {'°','±','²'} -- 3 different shadow backgrounds Lines = {{218,196,191,179,192,217}, -- single line borders {201,205,187,186,200,188}, -- double line borders {213,205,184,179,212,190}, -- double horizontal {214,196,183,186,211,189}, -- double vertical {' ',' ',' ',' ',' ',' '}} -- none Divider = {{195,196,180}, -- single style divider line {204,205,185}, {198,205,181}, -- double horizontal {199,196,182}, {' ',' ',' '}} Shadow = {176,177,178} -- 3 different shadow backgrounds end if
This was adapted fron D. Cuny's / Irv Mullins et al text mode dialogs.
Note this works equally well on a windows console (in fact looks a little nicer, as the lines come out as lines, and not ascii characters)
Next, the translators
--------------------------------------------------------------------------------------------------------------------- global function resolve_queue(sequence kq) --------------------------------------------------------------------------------------------------------------------- for i = 1 to length(kq) do if kq[1] = ESC then if kq[2] = -1 then return ESC elsif kq[2] = 79 then if kq[3] = 0 then return home elsif kq[3] = 101 then return endd elsif kq[3] = 80 then return F1 elsif kq[3] = 81 then return F1 + 1 elsif kq[3] = 82 then return F1 + 2 elsif kq[3] = 83 then return F1 + 3 end if elsif kq[2] = 91 then if kq[3] >= 65 and kq[3] <= 68 then if kq[3] = 65 then return up elsif kq[3] = 66 then return dn elsif kq[3] = 67 then return right else return left end if elsif kq[3] = 49 then if kq[4] = 126 then return home end if elsif kq[3] = 50 then if kq[4] = 126 then return insert end if elsif kq[3] = 51 then return del elsif kq[3] = 52 then return endd elsif kq[3] = 53 then return pgup elsif kq[3] = 54 then return pgdn else return F1 + kq[3] - 49 end if end if end if end for return -1 end function --------------------------------------------------------------------------------------------------------------------- global function wait_key_nn() --new non ncurses wait_key replacement for eu 3 --returns a single character, like versions previous to eu25t3 --will also return a single character with versions prior to eu25t3 --note lot of scrounging from ed.ex, RDS --------------------------------------------------------------------------------------------------------------------- atom key sequence kq object characters kq = {} --wait for the first key - less computing time! key = wait_key() --pre eu 3.0 compatability if EU_VERSION < 3 or PLAT = WIN32 then return key end if kq = {key} --now get the rest of the keys while 1 do key = get_key() if key = -1 then exit end if kq &= key end while --thats filled the sequence, now process it if length(kq) = 1 then if kq[1] = 127 then kq[1] = bksp end if return kq[1] end if --puts(1, "Key pressed") --for i = 1 to length(kq) do -- printf(1, "%d,", {kq[i]}) --end for key = resolve_queue(kq) return key end function --------------------------------------------------------------------------------------------------------------------- global function get_key_nn(object c) --replaces original get_key function for n0 ncurses eu version --this won't work if there are too many key presses too quickly, better to use a match --------------------------------------------------------------------------------------------------------------------- atom key sequence kq if EU_VERSION < 3 or PLAT = WIN32 then return c end if kq = {c} --the first element --now get the rest of the keys while 1 do key = get_key() if key = -1 then exit end if kq &= key end while --thats filled the sequence, now process it if length(kq) = 1 then if kq[1] = 127 then kq[1] = bksp end if return kq[1] end if --puts(1, "Key pressed") --for i = 1 to length(kq) do -- printf(1, "%d,", {kq[i]}) --end for key = resolve_queue(kq) return key end function --------------------------------------------------------------------------------------------------------------------- global function get_key_w(object c) --uses match, to check for up and downs only, from waiting room --------------------------------------------------------------------------------------------------------------------- atom key sequence kq if EU_VERSION < 3 or PLAT = WIN32 then return c end if kq = {c} --the first element --now get the rest of the keys --this will get multiple presses, and promptly ignore them in the compare while 1 do key = get_key() if key = -1 then exit end if kq &= key end while --thats filled the sequence, now process it if length(kq) = 1 then if kq[1] = 127 then kq[1] = bksp end if return kq[1] end if if match(KEY_UP, kq) > 0 then --KEY_UP sequence return up end if if match(KEY_DOWN, kq) > 0 then --KEY_DOWN sequence return dn end if return key end function
And then replace all instances of wait_key in your program, with wait_key_nn, and get_key with either get_key_nn, or get_key_w (the latter was a special case I needed for a dynamic list for speed, but is included here for completeness.
Thet get_key_nn and get_key_w reuire a parameter - this is the first paramet of get_key - ie a normal get_key is used to get the first character, and this is fed to the new functions. In real use
integer c c = get_key() if c != -1 then c = get_key_nn(c) end if
These form part of the Fdialogs library, an extended version of the Dialogs library for text mode interface provided by Irv Mullins, D. Cuny etc.
Most of the codes and code from resolve_strings() was pulled from ed, supplied with eu3.0, modified to read from a sequence, rather than the key buffer.
Chris Burch
