2015-12-30 10:03:52 +00:00
DEFSNG A - Z
SUB VkResetMenu 'clears internal keys and rebuilds primary menu
VkRemoveInternal
i = VkByRole ( "ROOT" )
c = 0
'add menu
IF VkHide < > 0 THEN
c = c + 1
i2 = VkNew
VkReLabel i2 , "Show"
VK ( i2 ) . parent = i
VK ( i2 ) . offsetX = VkDefaultWidth * c
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "SHOW"
VK ( i2 ) . w = VkNewKeySize
ELSE
c = c + 1
i2 = VkNew
VkReLabel i2 , "Hide"
VK ( i2 ) . parent = i
VK ( i2 ) . offsetX = VkDefaultWidth * c
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "HIDE"
VK ( i2 ) . w = VkNewKeySize
END IF
c = c + 1
i2 = VkNew
VkReLabel i2 , "File"
VK ( i2 ) . parent = i
VK ( i2 ) . offsetX = VkDefaultWidth * c
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "FILE"
VK ( i2 ) . w = VkNewKeySize
VK ( i2 ) . locks = 1
c = c + 1
i2 = VkNew
VkReLabel i2 , "Edit"
VK ( i2 ) . parent = i
VK ( i2 ) . offsetX = VkDefaultWidth * c
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "EDIT"
VK ( i2 ) . w = VkNewKeySize
VK ( i2 ) . locks = 1
c = c + 1
i2 = VkNew
VkReLabel i2 , "Size"
VK ( i2 ) . parent = i
VK ( i2 ) . offsetX = VkDefaultWidth * c
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "SIZE"
VK ( i2 ) . w = VkNewKeySize
VK ( i2 ) . locks = 1
c = c + 1
i2 = VkNew
VkReLabel i2 , "Abc.."
VK ( i2 ) . parent = i
VK ( i2 ) . offsetX = VkDefaultWidth * c
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "ABC."
VK ( i2 ) . w = VkNewKeySize
VK ( i2 ) . locks = 1
'POSTPONED UNTIL 2ND RELEASE
'c = c + 1
'i2 = VkNew
'VkReLabel i2, "Type"
'VK(i2).parent = i
'VK(i2).offsetX = VkDefaultWidth * c
'VK(i2).internal = 1
'VK(i2).role = "TYPE"
'VK(i2).w = VkNewKeySize
'VK(i2).locks = 1
'DEPRECATED (MOUSE PIPES REMOVED THE REQUIREMENT FOR INPUT MODE SELECTION)
'c = c + 1
'i2 = VkNew
'VkReLabel i2, "Input Mode"
'VK(i2).parent = i
'VK(i2).offsetX = VkDefaultWidth * c
'VK(i2).internal = 1
'VK(i2).role = "IMOD"
'VK(i2).w = VkNewKeySize
'VK(i2).locks = 1
END SUB
SUB VkSelectKey ( page )
VkDefaultSelectKeyPage = page
VkRemoveInternal
rt = VkByRole ( "ROOT" )
i2 = VkNew
VK ( i2 ) . offsetX = 0
VK ( i2 ) . offsetY = -1 * VkUnitStepY
VK ( i2 ) . parent = rt
VkReLabel i2 , CHR$ ( 26 )
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "NSET"
p = page + 1
VK ( i2 ) . state = p
i2 = VkNew
VK ( i2 ) . offsetX = 0
VK ( i2 ) . offsetY = -2 * VkUnitStepY
VK ( i2 ) . parent = rt
VkReLabel i2 , CHR$ ( 27 )
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "PSET"
p = page - 1
IF p < 1 THEN p = 1
VK ( i2 ) . state = p
'a = -1000
DIM range ( 100 , 1 TO 2 ) AS LONG
r = 0
'key groups (first because they are more useful than individual keys)
r = r + 1 : range ( r , 1 ) = -1001 : range ( r , 2 ) = range ( r , 1 ) 'Set: Full KB
r = r + 1 : range ( r , 1 ) = -1000 : range ( r , 2 ) = range ( r , 1 ) 'Set: F1-F12
r = r + 1 : range ( r , 1 ) = -1002 : range ( r , 2 ) = range ( r , 1 ) 'Set: Game Controller
r = r + 1 : range ( r , 1 ) = -1003 : range ( r , 2 ) = range ( r , 1 ) 'Set: Arrow Pad
r = r + 1 : range ( r , 1 ) = -1004 : range ( r , 2 ) = range ( r , 1 ) 'Set: WASD Pad
r = r + 1 : range ( r , 1 ) = -1005 : range ( r , 2 ) = range ( r , 1 ) 'Set: Ins-Home-PageUp Del-End-PageDown
r = r + 1 : range ( r , 1 ) = -1006 : range ( r , 2 ) = range ( r , 1 ) 'Set: Num Pad
'D-Pad
r = r + 1 : range ( r , 1 ) = 1000 : range ( r , 2 ) = 1004 'D-Pad
'"safe"/essential ASCII (reordered for convenience)
r = r + 1 : range ( r , 1 ) = 97 : range ( r , 2 ) = 122 'a-z
r = r + 1 : range ( r , 1 ) = 48 : range ( r , 2 ) = 57 '0-9
r = r + 1 : range ( r , 1 ) = 65 : range ( r , 2 ) = 90 'A-Z
r = r + 1 : range ( r , 1 ) = 32 : range ( r , 2 ) = 32 'SPACE
r = r + 1 : range ( r , 1 ) = 13 : range ( r , 2 ) = 13 'ENTER
r = r + 1 : range ( r , 1 ) = 8 : range ( r , 2 ) = 8 'BACKSPACE
r = r + 1 : range ( r , 1 ) = 9 : range ( r , 2 ) = 9 'TAB
r = r + 1 : range ( r , 1 ) = 33 : range ( r , 2 ) = 47 '" "-"/"
r = r + 1 : range ( r , 1 ) = 58 : range ( r , 2 ) = 64 '":"-"@"
r = r + 1 : range ( r , 1 ) = 91 : range ( r , 2 ) = 96 '"["-"`"
r = r + 1 : range ( r , 1 ) = 123 : range ( r , 2 ) = 126 '"{"-"~"
r = r + 1 : range ( r , 1 ) = 27 : range ( r , 2 ) = 27 'ESCAPE
r = r + 1 : range ( r , 1 ) = 1005 : range ( r , 2 ) = 1035 '(see below)
'arrow keys
'INSERT, etc
'F1-F12
'standard modifier keys (SHIFT, ALT, etc)
'other special keys (Windows key, ...)
'extended ASCII
r = r + 1 : range ( r , 1 ) = 127 : range ( r , 2 ) = 255
'"unsafe" ASCII (placed after all content to avoid confusion with arrows)
r = r + 1 : range ( r , 1 ) = 1 : range ( r , 2 ) = 7
r = r + 1 : range ( r , 1 ) = 10 : range ( r , 2 ) = 12
r = r + 1 : range ( r , 1 ) = 14 : range ( r , 2 ) = 26
'r = r + 1: range(r, 1) = 28: range(r, 2) = 31-4
ranges = r
a = range ( 1 , 1 )
FOR cpage = 1 TO page
FOR y = 0 TO -3 STEP -1
FOR x = 1 TO 7
IF cpage = page THEN
i2 = VkNew
VK ( i2 ) . offsetX = x * VkDefaultWidth + 1
VK ( i2 ) . offsetY = y * VkUnitStepY
VK ( i2 ) . parent = rt
END IF
IF a < = 255 AND a > = 0 THEN
IF cpage = page THEN
VkReLabel i2 , CHR$ ( a )
IF a = 32 THEN VkReLabel i2 , "Space"
IF a = 13 THEN VkReLabel i2 , "Enter"
IF a = 8 THEN VkReLabel i2 , "Back Space"
IF a = 9 THEN VkReLabel i2 , "Tab"
IF a = 0 THEN VkReLabel i2 , "Null"
IF a = 7 THEN VkReLabel i2 , "Bell"
IF a = 10 THEN VkReLabel i2 , "Line Feed"
IF a = 11 THEN VkReLabel i2 , "Vert Tab"
IF a = 12 THEN VkReLabel i2 , "Form Feed"
IF a = 27 THEN VkReLabel i2 , "Esc"
IF a = 255 THEN VkReLabel i2 , "Nbsp"
VK ( i2 ) . event . keydown = a
END IF
ELSE
label$ = "?"
code = 63
lockIsTemporary = 0
locks = 0
'key sets
IF a = -1000 THEN label$ = "F1-F12" : code = a
IF a = -1001 THEN label$ = "Full KB" : code = a
IF a = -1002 THEN label$ = "Game Controller" : code = a
IF a = -1003 THEN label$ = "Arrow Pad" : code = a
IF a = -1004 THEN label$ = "WASD Pad" : code = a
IF a = -1005 THEN label$ = "Ins-Home-PageUp Del-End-PageDown" : code = a
IF a = -1006 THEN label$ = "Num Pad" : code = a
n = 1000 - 1
n = n + 1 : IF a = n THEN label$ = "Virtual Joystick" : code = -1
'n = n + 1: IF a = n THEN label$ = CHR$(24) + "[UP-ARROW]": code = VK_KEY_UP
'n = n + 1: IF a = n THEN label$ = CHR$(25) + "[DOWN-ARROW]": code = VK_KEY_DOWN
'n = n + 1: IF a = n THEN label$ = CHR$(27) + "[LEFT-ARROW]": code = VK_KEY_LEFT
'n = n + 1: IF a = n THEN label$ = CHR$(26) + "[RIGHT-ARROW]": code = VK_KEY_RIGHT
n = n + 1 : IF a = n THEN label$ = CHR$ ( 24 ) : code = VK_KEY_UP
n = n + 1 : IF a = n THEN label$ = CHR$ ( 25 ) : code = VK_KEY_DOWN
n = n + 1 : IF a = n THEN label$ = CHR$ ( 27 ) : code = VK_KEY_LEFT
n = n + 1 : IF a = n THEN label$ = CHR$ ( 26 ) : code = VK_KEY_RIGHT
n = n + 1 : IF a = n THEN label$ = "Ins" : code = VK_KEY_INSERT
n = n + 1 : IF a = n THEN label$ = "Del" : code = VK_KEY_DELETE
n = n + 1 : IF a = n THEN label$ = "Home" : code = VK_KEY_HOME
n = n + 1 : IF a = n THEN label$ = "End" : code = VK_KEY_END
n = n + 1 : IF a = n THEN label$ = "Page Up" : code = VK_KEY_PAGE_UP
n = n + 1 : IF a = n THEN label$ = "Page Down" : code = VK_KEY_PAGE_DOWN
n = n + 1 : IF a = n THEN label$ = "F1" : code = VK_KEY_F1
n = n + 1 : IF a = n THEN label$ = "F2" : code = VK_KEY_F2
n = n + 1 : IF a = n THEN label$ = "F3" : code = VK_KEY_F3
n = n + 1 : IF a = n THEN label$ = "F4" : code = VK_KEY_F4
n = n + 1 : IF a = n THEN label$ = "F5" : code = VK_KEY_F5
n = n + 1 : IF a = n THEN label$ = "F6" : code = VK_KEY_F6
n = n + 1 : IF a = n THEN label$ = "F7" : code = VK_KEY_F7
n = n + 1 : IF a = n THEN label$ = "F8" : code = VK_KEY_F8
n = n + 1 : IF a = n THEN label$ = "F9" : code = VK_KEY_F9
n = n + 1 : IF a = n THEN label$ = "F10" : code = VK_KEY_F10
n = n + 1 : IF a = n THEN label$ = "F11" : code = VK_KEY_F11
n = n + 1 : IF a = n THEN label$ = "F12" : code = VK_KEY_F12
n = n + 1
IF a = n THEN
label$ = "Shift (Left)"
code = VK_KEY_LSHIFT
locks = 1 : lockIsTemporary = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Shift (Right)"
code = VK_KEY_RSHIFT
locks = 1 : lockIsTemporary = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Ctrl (Left)"
code = VK_KEY_LCTRL
locks = 1 : lockIsTemporary = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Ctrl (Right)"
code = VK_KEY_RCTRL
locks = 1 : lockIsTemporary = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Alt (Left)"
code = VK_KEY_LALT
locks = 1 : lockIsTemporary = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Alt (Right)"
code = VK_KEY_RALT
locks = 1 : lockIsTemporary = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Caps Lock"
code = VK_KEY_CAPSLOCK
locks = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Num Lock"
code = VK_KEY_NUMLOCK
locks = 1
END IF
n = n + 1
IF a = n THEN
label$ = "Scr Lock"
code = VK_KEY_SCROLLOCK
locks = 1
END IF
n = n + 1 : IF a = n THEN label$ = "Win (Left)" : code = VK_KEY_LSUPER
n = n + 1 : IF a = n THEN label$ = "Win (Right)" : code = VK_KEY_RSUPER
n = n + 1 : IF a = n THEN label$ = "Apple (Left)" : code = VK_KEY_LMETA
n = n + 1 : IF a = n THEN label$ = "Apple (Right)" : code = VK_KEY_RMETA
'SCREEN 2
'PRINT n-1
'CONST KEY_KP0& = 100256
'CONST KEY_KP1& = 100257
'CONST KEY_KP2& = 100258
'CONST KEY_KP3& = 100259
'CONST KEY_KP4& = 100260
'CONST KEY_KP5& = 100261
'CONST KEY_KP6& = 100262
'CONST KEY_KP7& = 100263
'CONST KEY_KP8& = 100264
'CONST KEY_KP9& = 100265
'CONST KEY_KP_PERIOD& = 100266
'CONST KEY_KP_DIVIDE& = 100267
'CONST KEY_KP_MULTIPLY& = 100268
'CONST KEY_KP_MINUS& = 100269
'CONST KEY_KP_PLUS& = 100270
'CONST KEY_KP_ENTER& = 100271
'CONST KEY_KP_INSERT& = 200000
'CONST KEY_KP_END& = 200001
'CONST KEY_KP_DOWN& = 200002
'CONST KEY_KP_PAGE_DOWN& = 200003
'CONST KEY_KP_LEFT& = 200004
'CONST KEY_KP_MIDDLE& = 200005
'CONST KEY_KP_RIGHT& = 200006
'CONST KEY_KP_HOME& = 200007
'CONST KEY_KP_UP& = 200008
'CONST KEY_KP_PAGE_UP& = 200009
'CONST KEY_KP_DELETE& = 200010
size = LEN ( label$ )
text$ = label$
IF INSTR ( text$ , " " ) THEN
text2$ = RIGHT$ ( text$ , LEN ( text$ ) - INSTR ( text$ , " " ) )
text$ = LEFT$ ( text$ , INSTR ( text$ , " " ) - 1 )
IF LEN ( text2$ ) > LEN ( text$ ) THEN size = LEN ( text2$ ) ELSE size = LEN ( text$ )
END IF
IF size > 5 THEN
x = x + ( size - 5 ) \ 5 + 1
IF cpage = page THEN VK ( i2 ) . w = VkDefaultWidth + ( ( size - 5 ) \ 5 + 1 ) * VkDefaultWidth
END IF
IF cpage = page THEN
VkReLabel i2 , label$
VK ( i2 ) . event . keydown = code
VK ( i2 ) . lockIsTemporary = lockIsTemporary
VK ( i2 ) . locks = locks
END IF
END IF
IF cpage = page THEN
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "VALU"
END IF
'END IF
a = a + 1
FOR r = 0 TO ranges
IF range ( r , 2 ) + 1 = a THEN
IF r = ranges THEN noMore = 1 ELSE a = range ( r + 1 , 1 )
EXIT FOR
END IF
NEXT
IF noMore THEN EXIT SUB
NEXT
NEXT
NEXT
END SUB
SUB VkPress ( i )
role$ = VK ( i ) . role
IF role$ = "ROOT" THEN
VkAddShiftedKey = 0
IF VK ( i ) . locked = 0 THEN
VK ( i ) . held = 1
VK ( i ) . locked = 1
VkResetMenu
ELSE
'remove all internal keys
VkRemoveInternal
VK ( i ) . locked = 0
END IF
EXIT SUB
END IF
IF role$ = "AA.." THEN
IF VkSelectedKey < > 0 THEN
IF VK ( VkSelectedKey ) . event . keydown > = 0 THEN
VkAddShiftedKey = 0
VkSelectKey VkDefaultSelectKeyPage
END IF
END IF
EXIT SUB
END IF
IF role$ = "^AA." THEN
IF VkSelectedKey < > 0 THEN
IF VK ( VkSelectedKey ) . event . keydown > = 0 THEN
VkAddShiftedKey = 1
VkSelectKey VkDefaultSelectKeyPage
END IF
END IF
EXIT SUB
END IF
IF role$ = "ADDK" THEN
VkSelectedKey = 0
VkAddShiftedKey = 0
VkSelectKey VkDefaultSelectKeyPage
EXIT SUB
END IF
IF role$ = "DELK" THEN
i2 = VkSelectedKey
IF i2 < > 0 THEN
'if this is a parent handle, all children need to be detached first
IF VK ( i2 ) . event . keydown = -2 THEN 'keyset handle
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . parent = 0
VK ( i3 ) . offsetX = 0
VK ( i3 ) . offsetY = 0
END IF
END IF
NEXT
END IF
VkRemove i2
VkSelectedKey = 0
VkResetMenu
END IF
EXIT SUB
END IF
IF role$ = "DSET" THEN
i2 = VkSelectedKey
hasChildren = 0
IF i2 < > 0 THEN
'if this is a parent handle, all children need to be deleted first
IF VK ( i2 ) . event . keydown = -2 THEN 'keyset handle
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VkRemove i3
hasChildren = 1
END IF
END IF
NEXT
END IF
IF hasChildren THEN
VkRemove i2
VkSelectedKey = 0
VkResetMenu
END IF
END IF
EXIT SUB
END IF
IF role$ = "DALL" THEN
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
IF VK ( i3 ) . internal = 0 THEN
VkRemove i3
END IF
END IF
NEXT
VkSelectedKey = 0
VkResetMenu
EXIT SUB
END IF
IF role$ = "EDIT" THEN
IF VK ( i ) . locked = 1 THEN
VkResetMenu
ELSE
VkHide = 0 'do not hide keybaord when editing
VkResetMenu
i = VkByRole ( role$ )
VK ( i ) . locked = 1
ox = VK ( i ) . offsetX
oy = 0
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Add Keys"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "ADDK"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Del Key"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "DELK"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Del Set"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "DSET"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Del All"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "DALL"
VK ( i2 ) . w = VkNewKeySize
END IF
VkReDraw = 1
EXIT SUB
END IF 'edit
IF role$ = "HIDE" THEN
VkHide = -1
VkResetMenu
VkPress VkByRole ( "ROOT" )
EXIT SUB
END IF
IF role$ = "SHOW" THEN
VkHide = 0
VkResetMenu
VkPress VkByRole ( "ROOT" )
EXIT SUB
END IF
IF role$ = "SAVE" THEN
VkSave
VkResetMenu
END IF
IF role$ = "FILE" THEN
IF VK ( i ) . locked = 1 THEN
VkResetMenu
ELSE
VkHide = 0 'do not hide keybaord when editing
VkResetMenu
i = VkByRole ( role$ )
VK ( i ) . locked = 1
ox = VK ( i ) . offsetX
oy = 0
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Save"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "SAVE"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Reset"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "RSET"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Exit"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "EXIT"
VK ( i2 ) . w = VkNewKeySize
END IF
VkReDraw = 1
EXIT SUB
END IF 'FILE
IF role$ = "EXIT" THEN
'remove ALL keys, even root keys
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
VkRemove i3
END IF
NEXT
VkSelectedKey = 0
VkExiting = 1
EXIT SUB
END IF
IF role$ = "RSET" THEN
'remove all keys
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
IF VK ( i3 ) . internal = 0 THEN
VkRemove i3
END IF
END IF
NEXT
VkSelectedKey = 0
'load default layout (if one exists)
VkFile$ = ""
if _FILEEXISTS ( appRootPath$ + "virtual_keyboard_layout_default.txt" ) then VkFile$ = appRootPath$ + "virtual_keyboard_layout_default.txt"
if VkFile$ < > "" then
fh = FREEFILE
OPEN VkFile$ FOR INPUT AS # fh
LINE INPUT # fh , json$
CLOSE # fh
root = QB_NODESET_deserialize ( json$ , "json" )
DIM oldVkWidthInUnits AS LONG
oldVkWidthInUnits = VkWidthInUnits
VkWidthInUnits = 90
DIM rootValueNode AS LONG
rootValueNode = QB_NODE_withLabel ( root , "width" )
if rootValueNode then VkWidthInUnits = QB_NODE_valueOfLabel_long ( root , "width" )
if VkWidthInUnits < > oldVkWidthInUnits then
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
VK ( i3 ) . reDraw = 1
END IF
NEXT
VkReset = 1
END IF
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( root ) , "keys" ) ) , 0
QB_NODE_destroy root
end if
VkResetMenu
EXIT SUB
END IF
IF role$ = "SCUP" THEN
VkWidthInUnits = VkWidthInUnits -6
if VkWidthInUnits < 90 -6 * 7 then VkWidthInUnits = 90 -6 * 7
'force all keys to be redrawn
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
VK ( i3 ) . reDraw = 1
END IF
NEXT
VkReset = 1
EXIT SUB
END IF
IF role$ = "SCDN" THEN
VkWidthInUnits = VkWidthInUnits + 6
if VkWidthInUnits > 90 + 6 * 20 then VkWidthInUnits = 90 + 6 * 20
'force all keys to be redrawn
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
VK ( i3 ) . reDraw = 1
END IF
NEXT
VkReset = 1
EXIT SUB
END IF
IF role$ = "BIGR" THEN
i2 = VkSelectedKey
IF i2 < > 0 THEN
IF VK ( i2 ) . event . keydown > = 0 THEN
VK ( i2 ) . w = VK ( i2 ) . w + 1
VK ( i2 ) . reDraw = 1
END IF
END IF
EXIT SUB
END IF
IF role$ = "SMLR" THEN
i2 = VkSelectedKey
IF i2 < > 0 THEN
IF VK ( i2 ) . event . keydown > = 0 THEN
VK ( i2 ) . w = VK ( i2 ) . w - 1
IF VK ( i2 ) . w < 2 THEN VK ( i2 ) . w = 2
VK ( i2 ) . reDraw = 1
END IF
END IF
EXIT SUB
END IF
IF role$ = "SIZE" THEN
IF VK ( i ) . locked = 1 THEN
VkResetMenu
ELSE
VkHide = 0 'do not hide keybaord when editing
VkResetMenu
i = VkByRole ( role$ )
VK ( i ) . locked = 1
ox = VK ( i ) . offsetX
oy = 0
oy = oy + 1
i2 = VkNew
VkReLabel i2 , chr$ ( 17 ) + chr$ ( 196 ) + chr$ ( 196 ) + chr$ ( 16 )
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "BIGR"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , chr$ ( 196 ) + chr$ ( 16 ) + chr$ ( 17 ) + chr$ ( 196 )
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "SMLR"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Scale Up"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "SCUP"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Scale Down"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "SCDN"
VK ( i2 ) . w = VkNewKeySize
END IF
VkReDraw = 1
EXIT SUB
END IF 'SIZE
IF role$ = "ABC." THEN
IF VK ( i ) . locked = 1 THEN
VkResetMenu
ELSE
VkHide = 0 'do not hide keybaord when editing
VkResetMenu
i = VkByRole ( role$ )
VK ( i ) . locked = 1
ox = VK ( i ) . offsetX
oy = 0
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Aa..."
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "AA.."
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Aa... ^^"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "^AA."
VK ( i2 ) . w = VkNewKeySize
END IF
VkReDraw = 1
EXIT SUB
END IF 'ABC.
IF role$ = "TYPE" THEN
IF VK ( i ) . locked = 1 THEN
VkResetMenu
ELSE
VkHide = 0 'do not hide keybaord when editing
VkResetMenu
i = VkByRole ( role$ )
VK ( i ) . locked = 1
ox = VK ( i ) . offsetX
oy = 0
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Locks"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "LOCK"
VK ( i2 ) . w = VkNewKeySize
oy = oy + 1
i2 = VkNew
VkReLabel i2 , "Waits Press"
VK ( i2 ) . parent = VK ( i ) . parent
VK ( i2 ) . offsetX = ox
VK ( i2 ) . offsetY = - oy * VkUnitStepY
VK ( i2 ) . internal = 1
VK ( i2 ) . role = "STKY"
VK ( i2 ) . w = VkNewKeySize
END IF
VkReDraw = 1
EXIT SUB
END IF 'TYPE
'IF role$ = "IMOD" THEN
' IF VK(i).locked = 1 THEN
' VkResetMenu
' ELSE
' VkResetMenu
' i = VkByRole(role$)
' VK(i).locked = 1
' ox = VK(i).offsetX
' oy = 0
'
' oy = oy + 1
' i2 = VkNew
' VkReLabel i2, "Share Input"
' VK(i2).parent = VK(i).parent
' VK(i2).offsetX = ox
' VK(i2).offsetY = -oy * VkUnitStepY
' VK(i2).internal = 1
' VK(i2).locks = 1
' IF VkSharedInputMode <> 0 THEN VK(i2).locked = 1
' VK(i2).role = "IMSH"
' VK(i2).w = VkNewKeySize
'
' oy = oy + 1
' i2 = VkNew
' VkReLabel i2, "Excl- usive"
' VK(i2).parent = VK(i).parent
' VK(i2).offsetX = ox
' VK(i2).offsetY = -oy * VkUnitStepY
' VK(i2).internal = 1
' VK(i2).locks = 1
' IF VkSharedInputMode = 0 THEN VK(i2).locked = 1
' VK(i2).role = "IMEX"
' VK(i2).w = VkNewKeySize
'
' END IF
' VkReDraw = 1
' EXIT SUB
'END IF 'TYPE
'IF role$ = "IMSH" THEN
' i3 = VkByRole("IMSH")
' VK(i3).locked = 1
' i3 = VkByRole("IMEX")
' VK(i3).locked = 0
' VkSharedInputMode = -1
' VkReDraw = 1
' DO WHILE func__mouseinput_exclusive: LOOP
' DO WHILE _MOUSEINPUT: LOOP
' mouseinput_mode 0
' EXIT SUB
'END IF
'IF role$ = "IMEX" THEN
' i3 = VkByRole("IMSH")
' VK(i3).locked = 0
' i3 = VkByRole("IMEX")
' VK(i3).locked = 1
' VkSharedInputMode = 0
' VkReDraw = 1
' DO WHILE func__mouseinput_exclusive: LOOP
' DO WHILE _MOUSEINPUT: LOOP
' mouseinput_mode 1
' EXIT SUB
'END IF
IF VK ( i ) . role = "NSET" OR VK ( i ) . role = "PSET" THEN
page = VK ( i ) . state
VkSelectKey page
EXIT SUB
END IF
IF VK ( i ) . role = "USER" THEN
rt = VkByRole ( "ROOT" )
IF VK ( rt ) . locked < > 0 THEN
'select key
VkSelectedKey = i
VkReDraw = 1
EXIT SUB
END IF
EXIT SUB
END IF
IF VK ( i ) . role = "VALU" THEN
i3 = VkByRole ( "ROOT" )
IF VK ( i ) . event . keydown < = -1000 THEN 'Full KB
'add parent (handle) key
i2 = VkNew
VK ( i2 ) . x = VK ( i3 ) . x + VkDefaultWidth * 0 + 1
VK ( i2 ) . y = VK ( i3 ) . y - VkDefaultWidth * 1
VkReLabel i2 , CHR$ ( 240 )
VK ( i2 ) . role = "USER"
VK ( i2 ) . h = CINT ( VkUnitStepY / 2 )
VK ( i2 ) . event . keydown = -2 'a "keySet"
END IF
IF VK ( i ) . event . keydown = -1004 THEN 'WASD Pad
json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qa\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_A\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qd\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_D\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qw\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_W\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qs\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_S\q}}}]}"
keyset = QB_NODESET_deserialize ( VkGetQuotedString ( json$ ) , "json" )
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( keyset ) , "keys" ) ) , i2
FOR i3 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . offsetY = VK ( i3 ) . offsetY - VkDefaultWidth * 1
END IF
END IF
NEXT
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
IF VK ( i ) . event . keydown = -1003 THEN 'Arrow Pad
json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2192\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RIGHT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2190\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LEFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2193\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOWN\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2191\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UP\q}}}]}"
keyset = QB_NODESET_deserialize ( VkGetQuotedString ( json$ ) , "json" )
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( keyset ) , "keys" ) ) , i2
FOR i3 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . offsetY = VK ( i3 ) . offsetY - VkDefaultWidth * 1
END IF
END IF
NEXT
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
'Ins-Home-PageUp Del-End-PageDown
IF VK ( i ) . event . keydown = -1005 THEN 'Ins-Home-PageUp Del-End-PageDown
json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qPage Down\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_PAGE_DOWN\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qPage Up\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_PAGE_UP\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qEnd\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_END\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qHome\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_HOME\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qDel\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DELETE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qIns\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_INSERT\q}}}]}"
keyset = QB_NODESET_deserialize ( VkGetQuotedString ( json$ ) , "json" )
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( keyset ) , "keys" ) ) , i2
FOR i3 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . offsetY = VK ( i3 ) . offsetY - VkDefaultWidth * 2
END IF
END IF
NEXT
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
IF VK ( i ) . event . keydown = -1006 THEN 'Num Pad
json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q5\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_5\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q4\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_4\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q3\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_3\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q2\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_2\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q1\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_1\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:12,\qheight\q:6,\qlabel\q:\q0\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_0\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q6\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_6\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q7\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_7\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q8\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_8\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q/\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_FORWARD_SLASH\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q*\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_STAR\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:12,\qlabel\q:\q+\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_PLUS\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q-\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_MINUS\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qBack Space\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_BACKSPACE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:12,\qlabel\q:\qEnter\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ENTER\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q9\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_9\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q.\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOT\q}}}]}"
keyset = QB_NODESET_deserialize ( VkGetQuotedString ( json$ ) , "json" )
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( keyset ) , "keys" ) ) , i2
FOR i3 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . offsetY = VK ( i3 ) . offsetY - VkDefaultWidth * 5
END IF
END IF
NEXT
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
IF VK ( i ) . event . keydown = -1002 THEN 'Game Controller
json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:70,\qoffsetY\q:18,\qwidth\q:20,\qheight\q:6,\qlabel\q:\qR\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_R\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:18,\qwidth\q:20,\qheight\q:6,\qlabel\q:\qL\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_L\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:75,\qoffsetY\q:0,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qB\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_B\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:80,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qA\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_A\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:75,\qoffsetY\q:12,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qX\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_X\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:70,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qY\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_Y\q}}},{\qtype\q:\qjoystick\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qVirtual Joystick\q,\qevents\q:{\qup\q:{\qkeyCode\q:\qKEY_UP\q},\qdown\q:{\qkeyCode\q:\qKEY_DOWN\q},\qleft\q:{\qkeyCode\q:\qKEY_LEFT\q},\qright\q:{\qkeyCode\q:\qKEY_RIGHT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:33,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qSpace\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_SPACE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:48,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qEnter\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ENTER\q}}}]}"
keyset = QB_NODESET_deserialize ( VkGetQuotedString ( json$ ) , "json" )
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( keyset ) , "keys" ) ) , i2
FOR i3 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . offsetY = VK ( i3 ) . offsetY - VkDefaultWidth * 4
END IF
END IF
NEXT
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
IF VK ( i ) . event . keydown = -1001 THEN 'Full KB
'no shifted characters:
'json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q`\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_REVERSE_APOSTROPHE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q1\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_1\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:9,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qq\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Q\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:15,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qw\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_W\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:21,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qe\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_E\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:27,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qr\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_R\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:33,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qt\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_T\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:39,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qy\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Y\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:45,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qu\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_U\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:51,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qi\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_I\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:57,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qo\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_O\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:63,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qp\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_P\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:69,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q[\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_OPEN_BRACKET_SQUARE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:75,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q]\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_CLOSE_BRACKET_SQUARE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q2\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_2\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:11,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qa\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_A\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:17,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qs\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_S\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:23,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qd\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_D\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:29,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qf\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_F\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:35,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qg\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_G\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:41,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qh\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_H\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:47,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qj\q,\qlocks\q:false,\qlockIsTempo
'with shifted characters:
json$ = " { \ qkeys \ q: [ { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 0 , \ qoffsetY \ q: 24 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ q ` \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_REVERSE_APOSTROPHE \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_TILDE \ q , \ qlabel \ q: \ q ~ \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 6 , \ qoffsetY \ q: 24 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ q1 \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_1 \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_EXCLAMATION \ q , \ qlabel \ q: \ q! \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 9 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qq \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_Q \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_Q \ q , \ qlabel \ q: \ qQ \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 15 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qw \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_W \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_W \ q , \ qlabel \ q: \ qW \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 21 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qe \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_E \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_E \ q , \ qlabel \ q: \ qE \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 27 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qr \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_R \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_R \ q , \ qlabel \ q: \ qR \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 33 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qt \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_T \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_T \ q , \ qlabel \ q: \ qT \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 39 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qy \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_Y \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_Y \ q , \ qlabel \ q: \ qY \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 45 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qu \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_U \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_U \ q , \ qlabel \ q: \ qU \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 51 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qi \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_I \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_I \ q , \ qlabel \ q: \ qI \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 57 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qo \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_O \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_O \ q , \ qlabel \ q: \ qO \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 63 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qp \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_P \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_UCASE_P \ q , \ qlabel \ q: \ qP \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 69 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ q [ \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_OPEN_BRACKET_SQUARE \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_OPEN_BRACKET_CURLY \ q , \ qlabel \ q: \ q { \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 75 , \ qoffsetY \ q: 18 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ q ] \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_CLOSE_BRACKET_SQUARE \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_CLOSE_BRACKET_CURLY \ q , \ qlabel \ q: \ q } \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 12 , \ qoffsetY \ q: 24 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ q2 \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_2 \ q } , \ qkeydownWithShift \ q: { \ qkeyCode \ q: \ qKEY_AT \ q , \ qlabel \ q: \ q@ \ q } } } , { \ qtype \ q: \ qkey \ q , \ qoffsetX \ q: 11 , \ qoffsetY \ q: 12 , \ qwidth \ q: 6 , \ qheight \ q: 6 , \ qlabel \ q: \ qa \ q , \ qlocks \ q: false , \ qlockIsTemporary \ q: false , \ qevents \ q: { \ qkeydown \ q: { \ qkeyCode \ q: \ qKEY_LCASE_A \ q } , \ qkeydownWithShift \ q: { \ qkeyCode
keyset = QB_NODESET_deserialize ( VkGetQuotedString ( json$ ) , "json" )
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( keyset ) , "keys" ) ) , i2
FOR i3 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . offsetY = VK ( i3 ) . offsetY - VkDefaultWidth * 5
END IF
END IF
NEXT
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
IF VK ( i ) . event . keydown = -1000 THEN 'F1-F12
json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:66,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF12\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F12\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:60,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF11\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F11\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:54,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF10\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F10\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:48,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF9\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F9\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:42,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF8\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F8\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:36,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF7\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F7\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:30,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF6\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F6\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:24,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF5\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F5\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF4\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F4\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF3\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F3\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF2\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F2\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF1\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F1\q}}}]}"
keyset = QB_NODESET_deserialize ( VkGetQuotedString ( json$ ) , "json" )
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( keyset ) , "keys" ) ) , i2
FOR i3 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i3 ) . parent = i2 THEN
VK ( i3 ) . offsetY = VK ( i3 ) . offsetY - VkDefaultWidth * 1
END IF
END IF
NEXT
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
addingNewKey = 0
IF VkSelectedKey < > 0 THEN
i2 = VkSelectedKey
ELSE
addingNewKey = 1
i2 = VkNew
VK ( i2 ) . x = VK ( i3 ) . x + VkDefaultWidth * 0 + 1
VK ( i2 ) . y = VK ( i3 ) . y - VkDefaultWidth * 1
END IF
' hasShiftedEvent AS LONG
' shiftedEvent AS VKEY_EVENT 'eg. when shifted or caps lock is on
' shiftedLabel AS STRING * 100
'VkAddShiftedKey
label$ = RTRIM$ ( VK ( i ) . label )
IF INSTR ( label$ , " (" ) > 1 AND INSTR ( label$ , ")" ) > 1 THEN
'strip meta info
label$ = LEFT$ ( label$ , INSTR ( label$ , " (" ) - 1 )
END IF
IF VkAddShiftedKey THEN
VkAddShiftedKey = 0
VK ( i2 ) . hasShiftedEvent = 1
VkReLabelShifted i2 , label$
VK ( i2 ) . shiftedEvent . keydown = VK ( i ) . event . keydown
ELSE
VkReLabel i2 , label$
VK ( i2 ) . event . keydown = VK ( i ) . event . keydown
VK ( i2 ) . locks = VK ( i ) . locks
VK ( i2 ) . lockIsTemporary = VK ( i ) . lockIsTemporary
END IF
'for a-z & A-Z automatically add their shifted key codes
IF addingNewKey < > 0 AND VkAddShiftedKey = 0 THEN
keyCode = VK ( i ) . event . keydown
shiftedKeyCode = keyCode
IF keyCode > = 97 AND keyCode < = 122 THEN shiftedKeyCode = keyCode - 32
IF keyCode > = 65 AND keyCode < = 90 THEN shiftedKeyCode = keyCode + 32
IF shiftedKeyCode < > keyCode THEN
VK ( i2 ) . hasShiftedEvent = 1
VK ( i2 ) . shiftedEvent . keydown = shiftedKeyCode
VK ( i2 ) . shiftedLabel = CHR$ ( shiftedKeyCode )
END IF
END IF
VK ( i2 ) . role = "USER"
VkPress ( VkByRole ( "ROOT" ) )
VkPress ( VkByRole ( "ROOT" ) )
VkSelectedKey = i2
EXIT SUB
END IF
END SUB
FUNCTION VkNew
VkReDraw = 1
i2 = 0
FOR i = 1 TO VkLast
IF VK ( i ) . active = 0 THEN
i2 = i
END IF
NEXT
IF i2 = 0 THEN i2 = i: VkLast = i
i = i2
VK ( i ) = VkEmpty
VK ( i ) . active = 1
VK ( i ) . x = 0
VK ( i ) . y = 0
VK ( i ) . w = VkDefaultWidth
VK ( i ) . h = VkUnitStepY
VK ( i ) . role = "UNKN"
VkNew = i
END FUNCTION
SUB VkRemove ( i )
VkReDraw = 1
VK ( i ) . active = 0
IF VK ( i ) . image THEN _FREEIMAGE VK ( i ) . image
IF VK ( i ) . subImage THEN _FREEIMAGE VK ( i ) . subImage
IF VK ( i ) . highlightImage THEN _FREEIMAGE VK ( i ) . highlightImage
IF VK ( i ) . selectedImage THEN _FREEIMAGE VK ( i ) . selectedImage
END SUB
SUB VkRemoveInternal
FOR i = 1 TO VkLast
IF VK ( i ) . active THEN
IF VK ( i ) . internal THEN
IF VK ( i ) . role < > "ROOT" THEN
VkRemove i
END IF
END IF
END IF
NEXT
END SUB
FUNCTION VkByRole ( role$ )
FOR i = 1 TO VkLast
IF VK ( i ) . active = 1 THEN
IF VK ( i ) . role = role$ THEN VkByRole = i: EXIT FUNCTION
END IF
NEXT
END FUNCTION
SUB VkLongPress ( i )
'avoid using long press for now because Windows delays MOUSEDOWN to MOUSEUP on touch
VkPress i
END SUB
SUB VkKeyRepeat ( i )
keydown VK ( i ) . keyRepeatKeyCode
VK ( i ) . lastKeydownTime = TIMER
VK ( i ) . keyRepeatCount = VK ( i ) . keyRepeatCount + 1
END SUB
SUB VkKeyDown ( i )
VkReDraw = 1
'called whenever user key down
IF VK ( i ) . internal = 0 THEN
rt = VkByRole ( "ROOT" )
IF VK ( rt ) . locked = 0 THEN 'not in edit mode
keydownvalue = VK ( i ) . event . keydown
IF VK ( i ) . hasShiftedEvent THEN
IF VkShiftInEffect THEN keydownvalue = VK ( i ) . shiftedEvent . keydown
END IF
IF keydownvalue < > 0 THEN
IF VK ( i ) . locks < > 0 OR VK ( i ) . lockIsTemporary < > 0 THEN
IF VK ( i ) . locked < > 0 THEN
keyup keydownvalue
VK ( i ) . locked = 0
VK ( i ) . held = 0
ELSE
keydown keydownvalue
VK ( i ) . locked = 1
VK ( i ) . held = 1
END IF
ELSE
VK ( i ) . held = 1
keydown keydownvalue
VK ( i ) . lastKeydownTime = TIMER
VK ( i ) . keyRepeatKeyCode = keydownvalue
VK ( i ) . keyRepeatCount = 0
END IF
END IF
END IF
IF VK ( i ) . locks = 0 THEN
FOR i2 = 1 TO VkLast
IF VK ( i2 ) . active THEN
IF VK ( i2 ) . internal = 0 THEN
IF i < > i2 THEN
IF VK ( i2 ) . locks THEN
IF VK ( i2 ) . locked THEN
IF VK ( i2 ) . lockIsTemporary THEN
VkKeyDown i2
END IF
END IF
END IF
END IF
END IF
END IF
NEXT
END IF
ELSE
VK ( i ) . held = 1
END IF
END SUB
SUB VkKeyUp ( i )
VkReDraw = 1
'called whenever user key down
IF VK ( i ) . internal = 0 THEN
rt = VkByRole ( "ROOT" )
IF VK ( rt ) . locked = 0 THEN 'not in edit mode
keydownvalue = VK ( i ) . event . keydown
IF VK ( i ) . hasShiftedEvent THEN
IF VkShiftInEffect THEN keydownvalue = VK ( i ) . shiftedEvent . keydown
END IF
IF keydownvalue < > 0 THEN
IF VK ( i ) . locks < > 0 OR VK ( i ) . lockIsTemporary < > 0 THEN
'do nothing
ELSE
keyup keydownvalue
VK ( i ) . held = 0
END IF
END IF
END IF
ELSE
VK ( i ) . held = 0
END IF
END SUB
SUB VkUpdate
if VkDelay > 0 then
VkTimeNow# = TIMER ( 0.001 )
if VkTimeNow# < VkDelayStartTime OR VkTimeNow# > = VkDelayStartTime + VkDelay THEN VkDelay = 0
exit sub
end if
if vkExited then
DO WHILE _MOUSEINPUT ( VkMousePipe )
_MOUSEINPUTPIPE VkMousePipe
LOOP
exit sub
end if
if VkExiting = 1 then VkExiting = 2
subOldDest = _DEST
subOldSource = _SOURCE
reDraw = VkReDraw
VkReDraw = 0
IF reDraw THEN
'SOUND 1000, .1
END IF
STATIC VkI
STATIC VKoldX
STATIC VKoldY
STATIC VKdragging
STATIC VKstart
STATIC mDownX
STATIC mDownY
STATIC omb
STATIC mb , mx , my
STATIC sx , sy
STATIC VkInit
'theme colors
'for user keys:
textCol& = _RGBA32 ( 255 , 255 , 255 , 192 )
borderCol& = _RGBA32 ( 32 , 32 , 32 , 192 )
borderSelectedCol& = _RGBA32 ( 255 , 255 , 255 , 192 )
bgCol& = _RGBA32 ( 96 , 96 , 96 , 128 )
bgHighlightCol& = _RGBA32 ( 128 , 128 , 128 , 128 )
'for customization:
InternalTextCol& = _RGBA32 ( 255 , 255 , 255 , 255 )
InternalBorderCol& = _RGBA32 ( 255 , 255 , 255 , 192 )
InternalBgCol& = _RGBA32 ( 0 , 0 , 0 , 192 )
InternalBgHighlightCol& = _RGBA32 ( 128 , 128 , 128 , 128 )
'Init is done once
IF VkInit = 0 THEN
VkWidthInUnits = 90 'default width in units (may be changed by loading a layout)
VkReset = 1
END IF
winX = _SCALEDWIDTH
winY = _SCALEDHEIGHT
IF winX < > VkWinX OR winY < > VkWinY THEN
'store new resolution
VkWinX = winX
VkWinY = winY
'clear overlay image (if one exists yet)
if VkOverlay then
_PUTIMAGE , VkClearTex , VkOverlay
end if
'beging a delay (wait until screen has fully repositioned)
VkDelayStartTime = TIMER ( 0.001 )
VkDelay = 1
VkDelayedReset = 1
exit sub
END IF
if VkDelayedReset = 1 then
VkDelayedReset = 0
VkReset = 1
end if
'Reset occurs whenever the screen size changes
IF VkReset = 1 THEN
VkReset = 0
'get new dimensions
VkWinX = winX
VkWinY = winY
'PRINT winX, winY
' END
sx = VkWinX: sy = VkWinY 'shortcuts
'we need to free the old overlay & backbuffer, but because they might be
'in use we cannot do it immediately
VkOverlay32 = _NEWIMAGE ( VkWinX , VkWinY , 32 )
VkOverlay = _COPYIMAGE ( VkOverlay32 , 33 )
VkBackbuffer = _COPYIMAGE ( VkOverlay32 , 33 )
_FREEIMAGE VkOverlay32
VkUnitSize = sx / VkWidthInUnits
h = CINT ( VkUnitStepY * VkUnitSize * 0.5 )
'VkFont = _LOADFONT("c:\windows\fonts\lucon.ttf", CINT(h))
'VkFontSmall = _LOADFONT("c:\windows\fonts\lucon.ttf", CINT(h * 0.5))
'generic textures
VkReDraw = 1
FOR i = 1 TO VkLast
IF VK ( i ) . active THEN
VK ( i ) . reDraw = 1
END IF
NEXT
END IF 'reset
IF VkInit = 0 THEN
VkClearTex = VkColTex ( _RGBA32 ( 0 , 0 , 0 , 0 ) ) : _DONTBLEND VkClearTex
i = VkNew
VK ( i ) . x = 0 'VkDefaultWidth
VK ( i ) . y = VkUnitStepY * 4 '*** do not modify or scaled up keybaord will be off screen***
VK ( i ) . w = VkDefaultWidth
VK ( i ) . h = VkUnitStepY
VK ( i ) . role = "ROOT"
VK ( i ) . internal = 1
VK ( i ) . locks = 1
VkReLabel i , "KB" 'CHR$(15)
VkLoad
END IF
VkInit = 1
IF reDraw THEN
'clear backbuffer
_DONTBLEND VkBackbuffer
_PUTIMAGE , VkClearTex , VkBackbuffer
_BLEND VkBackbuffer
'correct offsets of keys relative to parents
FOR i = 1 TO VkLast
IF VK ( i ) . active THEN
p = VK ( i ) . parent
IF p THEN
VK ( i ) . x = VK ( p ) . x + VK ( i ) . offsetX
VK ( i ) . y = VK ( p ) . y + VK ( i ) . offsetY
END IF
END IF
NEXT
rt = VkByRole ( "ROOT" )
shiftInEffect = VkShiftInEffect
'render keys
FOR internal = 0 TO 1
FOR i = 1 TO VkLast
IF VK ( i ) . active THEN
IF VK ( i ) . internal = internal AND ( VK ( i ) . event . keydown < > -2 OR VK ( rt ) . locked < > 0 ) and ( internal = 1 or vkHide = 0 ) THEN
x = VK ( i ) . x * VkUnitSize
y = VK ( i ) . y * VkUnitSize
w = VK ( i ) . w
h = VK ( i ) . h
x1 = INT ( x )
x2 = INT ( x + VkUnitSize * w ) - 1
y1 = sy - 1 - INT ( y )
y2 = sy - 1 - INT ( y + VkUnitSize * h ) + 1
w2 = x2 - x1 + 1 'pixel metrics
h2 = y1 - y2 + 1
'get key colors
cText& = textCol&
cBorder& = borderCol&
cBg& = bgCol&
cBgHighlight& = bgHighlightCol&
IF VK ( i ) . internal THEN
cText& = InternalTextCol&
cBorder& = InternalBorderCol&
cBg& = InternalBgCol&
cBgHighlight& = InternalBgHighlightCol&
END IF
IF VK ( i ) . event . keydown = -1 AND VK ( i ) . internal = 0 THEN 'D-PAD
're-calculate dimensions
x = ( VK ( i ) . x - VkDefaultWidth ) * VkUnitSize
y = ( VK ( i ) . y - VkUnitStepY ) * VkUnitSize
w = VK ( i ) . w * 3
h = VK ( i ) . h * 3
x1 = INT ( x )
x2 = INT ( x + VkUnitSize * w ) - 1
y1 = sy - 1 - INT ( y )
y2 = sy - 1 - INT ( y + VkUnitSize * h ) + 1
w2 = x2 - x1 + 1 'pixel metrics
h2 = y1 - y2 + 1
create = 0
IF VK ( i ) . image < > 0 AND create = 0 THEN
'has required size changed?
iw = _WIDTH ( VK ( i ) . image )
ih = _HEIGHT ( VK ( i ) . image )
IF iw < > w2 OR ih < > h2 THEN
create = 1
END IF
END IF
IF VK ( i ) . reDraw THEN VK ( i ) . reDraw = 0 : create = 1
IF create THEN
'invalidate
IF VK ( i ) . image < > 0 THEN _FREEIMAGE VK ( i ) . image: VK ( i ) . image = 0
IF VK ( i ) . subImage < > 0 THEN _FREEIMAGE VK ( i ) . subImage: VK ( i ) . subImage = 0
END IF
IF VK ( i ) . image = 0 THEN
'soft render base
defKey = _NEWIMAGE ( w2 , h2 , 32 )
_DEST defKey
_DONTBLEND
dpcx = w2 \ 2 : dpcy = h2 \ 2
dprad = w2 \ 2 - 3
CIRCLE ( dpcx , dpcy ) , dprad , _RGBA32 ( 255 , 255 , 255 , 255 )
PAINT ( dpcx , dpcy ) , cBg& , _RGBA32 ( 255 , 255 , 255 , 255 )
'CIRCLE (dpcx, dpcy), dprad, _RGBA32(_RED32(cBg&), _GREEN32(cBg&), _BLUE32(cBg&), _ALPHA32(cBg&) * 0.75)
a = _ALPHA32 ( cBg& )
FOR r = dprad TO dprad + 10 STEP 0.15
a = a - 10
IF a < 0 THEN EXIT FOR
CIRCLE ( dpcx , dpcy ) , r , _RGBA32 ( _RED32 ( cBg& ) , _GREEN32 ( cBg& ) , _BLUE32 ( cBg& ) , a )
NEXT
_BLEND
'conv to hw
VK ( i ) . image = _COPYIMAGE ( defKey , 33 )
_FREEIMAGE defKey
'soft render stick
defKey = _NEWIMAGE ( w2 , h2 , 32 )
_DEST defKey
_DONTBLEND
dprad = dprad / 2.5
CIRCLE ( dpcx , dpcy ) , dprad , _RGBA32 ( 255 , 255 , 255 , 255 )
PAINT ( dpcx , dpcy ) , _RGBA32 ( 255 , 255 , 255 , 128 ) , _RGBA32 ( 255 , 255 , 255 , 255 )
a = 128
FOR r = dprad TO dprad + 10 STEP 0.15
a = a - 10
IF a < 0 THEN EXIT FOR
CIRCLE ( dpcx , dpcy ) , r , _RGBA32 ( 255 , 255 , 255 , a )
NEXT
_BLEND
'conv to hw
VK ( i ) . subImage = _COPYIMAGE ( defKey , 33 )
_FREEIMAGE defKey
END IF
dpadx = VK ( i ) . dpad . x: dpady = VK ( i ) . dpad . y
IF VkHide = 0 OR VK ( i ) . internal < > 0 THEN
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . image , VkBackbuffer
_PUTIMAGE ( x1 + dpadx * VkUnitSize * VkDefaultWidth * 0.89 , y2 + dpady * VkUnitSize * VkDefaultWidth * 0.89 ) , VK ( i ) . subImage , VkBackbuffer
END IF
GOTO special_key
END IF
'standard key
create = 0
IF VK ( i ) . image < > 0 AND create = 0 THEN
'has required size changed?
iw = _WIDTH ( VK ( i ) . image )
ih = _HEIGHT ( VK ( i ) . image )
IF iw < > w2 OR ih < > h2 THEN
create = 1
END IF
END IF
IF VK ( i ) . reDraw THEN VK ( i ) . reDraw = 0 : create = 1
IF create THEN
'invalidate
IF VK ( i ) . image < > 0 THEN _FREEIMAGE VK ( i ) . image: VK ( i ) . image = 0
IF VK ( i ) . highlightImage < > 0 THEN _FREEIMAGE VK ( i ) . highlightImage: VK ( i ) . highlightImage = 0
IF VK ( i ) . selectedImage < > 0 THEN _FREEIMAGE VK ( i ) . selectedImage: VK ( i ) . selectedImage = 0
END IF
IF VK ( i ) . image = 0 THEN
'soft render default key
FOR shiftedPass = 0 TO 1
IF shiftedPass = 0 OR ( shiftedPass = 1 AND VK ( i ) . hasShiftedEvent < > 0 ) THEN
FOR pass = 1 TO 3
defKey = _NEWIMAGE ( w2 , h2 , 32 )
_DEST defKey
_DONTBLEND
IF pass < > 2 THEN LINE ( 0 , 0 ) - ( w2 - 1 , h2 - 1 ) , cBg& , BF
IF pass = 2 THEN LINE ( 0 , 0 ) - ( w2 - 1 , h2 - 1 ) , cBgHighlight& , BF
IF pass < > 3 THEN
LINE ( 0 , 0 ) - ( w2 - 1 , h2 - 1 ) , cBorder& , B
ELSE
LINE ( 0 , 0 ) - ( w2 - 1 , h2 - 1 ) , borderSelectedCol& , B
END IF
_BLEND
'add text
'convert label to image
text$ = RTRIM$ ( VK ( i ) . label )
IF shiftedPass THEN text$ = RTRIM$ ( VK ( i ) . shiftedLabel )
text2$ = ""
IF text$ < > "" THEN
lines = 1
IF INSTR ( text$ , " " ) THEN
lines = 2
text2$ = RIGHT$ ( text$ , LEN ( text$ ) - INSTR ( text$ , " " ) )
text$ = LEFT$ ( text$ , INSTR ( text$ , " " ) - 1 )
END IF
defKeyHeightInPixels = VkUnitStepY * VkUnitSize
'42.6 for screen 0 80x25
font = VkFindFont ( INT ( defKeyHeightInPixels / 2 ) ) 'ideally 20 for 80x25
IF lines = 2 OR LEN ( text$ ) > = 2 AND text$ < > "KB" THEN
font = VkFindFont ( INT ( defKeyHeightInPixels / 3.5 ) ) 'ideally 12 for 80x25
END IF
_FONT font
cw = _PRINTWIDTH ( text$ )
IF lines = 2 THEN
cw2 = _PRINTWIDTH ( text2$ )
IF cw2 > cw THEN cw = cw2
END IF
ch = _FONTHEIGHT
IF cw < > 0 AND ch < > 0 THEN
ox = w2 \ 2 - cw \ 2
oy = h2 \ 2 - ( ch * lines ) \ 2
' _PUTIMAGE ((x1 + x2) / 2 - cw / 2, (y1 + y2) / 2 - ch / 2), ci33, VkBackbuffer
_PRINTMODE _KEEPBACKGROUND
COLOR cText&
_CONTROLCHR OFF
_PRINTSTRING ( ox , oy ) , text$
IF text2$ < > "" THEN _PRINTSTRING ( ox , oy + ch ) , text2$
_CONTROLCHR ON
END IF 'cw <> 0 AND ch <> 0
END IF 'text$<>""
' _FONT font
' cw = _PRINTWIDTH(text$)
' IF lines = 2 THEN
' cw2 = _PRINTWIDTH(text2$)
' IF cw2 > cw THEN cw = cw2
' END IF
' ch = _FONTHEIGHT
' ' GOTO 1
' IF cw = 0 OR ch = 0 THEN GOTO 1
' ci = _NEWIMAGE(cw, ch * lines, 32)
' _DEST ci
' _FONT font
' _PRINTMODE _KEEPBACKGROUND
' COLOR textCol&
' _CONTROLCHR OFF
' _PRINTSTRING (0, 0), text$
' _PRINTSTRING (0, ch), text2$
' _CONTROLCHR ON
'IF VK(i).held THEN
' cBg& = cBgHighlight&
'END IF
'bgTex = VkColTex(bgCol&)
'borderTex = VkColTex(borderCol&)
''PRINT x1, y1, x2, y2
'_PUTIMAGE (x1 + 1, y2 + 1)-(x2 - 1, y1 - 1), bgTex, VkBackbuffer
'_PUTIMAGE (x1, y2)-(x2, y2), borderTex, VkBackbuffer
'_PUTIMAGE (x1, y2 + 1)-(x1, y1), borderTex, VkBackbuffer
'_PUTIMAGE (x2, y2 + 1)-(x2, y1), borderTex, VkBackbuffer
'_PUTIMAGE (x1 + 1, y1)-(x2 - 1, y1), borderTex, VkBackbuffer
''LINE (x1, y1)-(x2, y2), borderCol&, B
'' _BLEND
'' _BLEND bgTex
'IF g = 0 THEN
' g = 1
' ' _PUTIMAGE (0, 0)-(100, 100), bgTex
' ' _PUTIMAGE (50, 50)-(150, 150), borderTex
'END IF
'_FREEIMAGE bgTex
'_FREEIMAGE borderTex
'conv to hw
IF shiftedPass = 0 THEN
IF pass = 1 THEN VK ( i ) . image = _COPYIMAGE ( defKey , 33 )
IF pass = 2 THEN VK ( i ) . highlightImage = _COPYIMAGE ( defKey , 33 )
IF pass = 3 THEN VK ( i ) . selectedImage = _COPYIMAGE ( defKey , 33 )
ELSE
IF pass = 1 THEN VK ( i ) . shiftedImage = _COPYIMAGE ( defKey , 33 )
IF pass = 2 THEN VK ( i ) . shiftedHighlightImage = _COPYIMAGE ( defKey , 33 )
IF pass = 3 THEN VK ( i ) . shiftedSelectedImage = _COPYIMAGE ( defKey , 33 )
END IF
_FREEIMAGE defKey
NEXT 'pass
END IF
NEXT 'shiftedPass
'SOUND 1000, 0.1
END IF
'assume shift in effect
shifted = 0
IF VK ( i ) . hasShiftedEvent THEN
IF shiftInEffect THEN
shifted = 1
END IF
END IF
IF VkHide = 0 OR VK ( i ) . internal < > 0 THEN
IF shifted THEN
IF VkSelectedKey = i AND VK ( rt ) . locked < > 0 THEN
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . shiftedSelectedImage , VkBackbuffer
ELSE
IF VK ( i ) . locks THEN
IF VK ( i ) . locked THEN
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . shiftedHighlightImage , VkBackbuffer
ELSE
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . shiftedImage , VkBackbuffer
END IF
ELSE
IF VK ( i ) . held THEN
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . shiftedHighlightImage , VkBackbuffer
ELSE
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . shiftedImage , VkBackbuffer
END IF
END IF
END IF
ELSE
IF VkSelectedKey = i AND VK ( rt ) . locked < > 0 THEN
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . selectedImage , VkBackbuffer
ELSE
IF VK ( i ) . locks THEN
IF VK ( i ) . locked THEN
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . highlightImage , VkBackbuffer
ELSE
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . image , VkBackbuffer
END IF
ELSE
IF VK ( i ) . held THEN
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . highlightImage , VkBackbuffer
ELSE
_PUTIMAGE ( x1 , y2 ) , VK ( i ) . image , VkBackbuffer
END IF
END IF
END IF
END IF
END IF
''convert label to image
'text$ = RTRIM$(VK(i).label)
'IF text$ <> "" THEN
' lines = 1
' IF INSTR(text$, " ") THEN
' lines = 2
' text2$ = RIGHT$(text$, LEN(text$) - INSTR(text$, " "))
' text$ = LEFT$(text$, INSTR(text$, " ") - 1)
' END IF
' font = VkFont
' IF lines = 2 OR LEN(text$) > 1 THEN
' font = VkFontSmall
' END IF
' STATIC dummy32
' IF dummy32 = 0 THEN
' dummy32 = _NEWIMAGE(1, 1, 32)
' END IF
' olddest = _DEST
' _DEST dummy32
' _FONT font
' cw = _PRINTWIDTH(text$)
' IF lines = 2 THEN
' cw2 = _PRINTWIDTH(text2$)
' IF cw2 > cw THEN cw = cw2
' END IF
' ch = _FONTHEIGHT
' ' GOTO 1
' IF cw = 0 OR ch = 0 THEN GOTO 1
' ci = _NEWIMAGE(cw, ch * lines, 32)
' _DEST ci
' _FONT font
' _PRINTMODE _KEEPBACKGROUND
' COLOR textCol&
' _CONTROLCHR OFF
' _PRINTSTRING (0, 0), text$
' _PRINTSTRING (0, ch), text2$
' _CONTROLCHR ON
' ch = ch * lines
' ci33 = _COPYIMAGE(ci, 33)
' _FREEIMAGE ci
' 'IF VkFontScale = 1 THEN
' _PUTIMAGE ((x1 + x2) / 2 - cw / 2, (y1 + y2) / 2 - ch / 2), ci33, VkBackbuffer
' 'ELSE
' 'cw = cw / VkFontScale
' 'ch = ch / VkFontScale
' '_PUTIMAGE ((x1 + x2) / 2 - cw / 2, (y1 + y2) / 2 - ch / 2)-((x1 + x2) / 2 + cw / 2 - 1, (y1 + y2) / 2 + ch / 2 - 1), ci33, VkBackbuffer, , _SMOOTH
' 'END IF
' _FREEIMAGE ci33
' 1
' _DEST olddest
special_key:
' _DEST olddest
' END IF
END IF
END IF
NEXT
NEXT
'_PUTIMAGE (mx, my)-(mx + 100, my + 100), borderTex, VkBackbuffer
'_PUTIMAGE , VkBackbuffer, VkOverlay
_DONTBLEND VkBackbuffer
_PUTIMAGE , VkBackbuffer , VkOverlay
'_PUTIMAGE (0, 0)-(639, 399), VkOverlay
requestKeyboardOverlayImage VkOverlay
_BLEND VkBackbuffer
END IF 'reDraw
'key repeat
timeNow! = TIMER
FOR i = 1 TO VkLast
IF VK ( i ) . active THEN
IF VK ( i ) . internal = 0 THEN
IF VK ( i ) . lastKeydownTime < > 0 THEN 'only keys which can repeat will have this set
IF VK ( i ) . held THEN
IF VK ( i ) . keyRepeatCount = 0 THEN
IF ABS ( VK ( i ) . lastKeydownTime - timeNow! ) > VkDelayUntilFirstRepeat THEN
VkKeyRepeat i
END IF
ELSE
IF ABS ( VK ( i ) . lastKeydownTime - timeNow! ) > VkDelayUntilFollowingRepeats THEN
VkKeyRepeat i
END IF
END IF
END IF
END IF
END IF
END IF
NEXT
DO
mDown = 0
mUp = 0
mEvent = 0
if VkMousePipe = 0 then
VkMousePipe = _MOUSEPIPEOPEN 'create new pipe
end if
' IF VkSharedInputMode THEN
' VkGetMouse VkSharedMouseMx, VkSharedMouseMy, VkSharedMouseMb
' mb = VkSharedMouseMb
' mb = mb AND 1
' IF mb <> 0 THEN mb = -1
' mx = VkSharedMouseMx
' my = VkSharedMouseMy
' 'CALL INTERRUPT is a problem...
' 'if ((display_page->compatible_mode==1)||(display_page->compatible_mode==7)||(display_page->compatible_mode==13)) cpu.cx*=2;
' 'if (display_page->text){
' ' //note: a range from 0 to columns*8-1 is returned regardless of the number of actual pixels
' ' cpu.cx=(mx-0.5)*8.0;
' ' if (cpu.cx>=(display_page->width*8)) cpu.cx=(display_page->width*8)-1;
' ' //note: a range from 0 to rows*8-1 is returned regardless of the number of actual pixels
' ' //obselete line of code: cpu.dx=(((float)cpu.dx)/((float)(display_page->height*fontheight[display_page->font])))*((float)(display_page->height*8));//(mouse_y/height_in_pixels)*(rows*8)
' ' cpu.dx=(my-0.5)*8.0;
' ' if (cpu.dx>=(display_page->height*8)) cpu.dx=(display_page->height*8)-1;
' '}
' 'reverse adjustments made by CALL INTERRUPT
' IF _PIXELSIZE = 1 THEN 'legacy modes adjustment
' mx = mx \ 2
' END IF
' IF _PIXELSIZE = 0 THEN 'screen 0 adjustment
' mx = (mx / 8) + 0.5
' my = (my / 8) + 0.5
' END IF
' 'apply new adjustments
' IF _PIXELSIZE = 0 THEN 'screen 0 adjustment
' mx = mx * 8 - 4
' my = my * 16 - 8
' END IF
' IF mb = -1 AND omb = 0 THEN mDown = -1: mEvent = 1
' IF mb = 0 AND omb = -1 THEN mUp = -1: mEvent = 1
' omb = mb
' ELSE
DO WHILE _MOUSEINPUT ( VkMousePipe )
mb = _MOUSEBUTTON ( 1 , VkMousePipe )
mx = _MOUSEX ( VkMousePipe )
my = _MOUSEY ( VkMousePipe )
sw = _width ( 0 )
sh = _height ( 0 )
IF _PIXELSIZE = 0 THEN 'screen 0 adjustment
mx = mx * 8 - 4
my = my * 16 - 8
sw = sw * 8
sh = sh * 16
END IF
mx = CINT ( mx * ( _SCALEDWIDTH / sw ) )
my = CINT ( my * ( _SCALEDHEIGHT / sh ) )
IF mb = -1 AND omb = 0 THEN mDown = -1 : mEvent = 1 : EXIT DO
if VkMousePipeCapture = 0 then
_MOUSEINPUTPIPE VkMousePipe
end if
IF mb = 0 AND omb = -1 THEN
VkMousePipeCapture = 0
mUp = -1
mEvent = 1
EXIT DO
end if
LOOP
omb = mb
' END IF
rootId = VkByRole ( "ROOT" )
editMode = VK ( rootId ) . locked
IF mDown THEN
mDownX = mx
mDownY = my
i2 = 0
FOR internal = 1 TO 0 STEP -1
FOR i = VkLast TO 1 STEP -1
IF VK ( i ) . active THEN
IF VK ( i ) . internal = internal THEN
if internal = 1 or VkHide = 0 then
x = VK ( i ) . x * VkUnitSize
y = VK ( i ) . y * VkUnitSize
w = VK ( i ) . w
h = VK ( i ) . h
x1 = INT ( x )
x2 = INT ( x + VkUnitSize * w ) - 1
y1 = sy - 1 - INT ( y )
y2 = sy - 1 - INT ( y + VkUnitSize * h ) + 1
IF mx > = x1 AND mx < = x2 AND my > = y2 AND my < = y1 THEN
i2 = i
EXIT FOR
END IF
end if
END IF
END IF
NEXT
IF i2 THEN EXIT FOR
NEXT
IF i2 THEN
VkI = i2
VKoldX = VK ( i2 ) . x
VKoldY = VK ( i2 ) . y
VKdragging = 0
VKstart = TIMER ( 0.001 )
'VK(i2).held = -1
VkKeyDown i2
VkMousePipeCapture = 1
END IF
if VkMousePipeCapture = 0 then _MOUSEINPUTPIPE VkMousePipe
END IF
IF mUp THEN
IF VkI THEN
IF VK ( VkI ) . event . keydown = -1 THEN
IF editMode = 0 THEN
VkUpdateDPAD VkI , 0 , 0
END IF
END IF
VkKeyUp VkI
IF VKdragging = 0 THEN
VKend = TIMER ( 0.001 )
duration = VKend - VKstart
IF duration > 0.5 THEN
VkLongPress ( VkI )
ELSE
VkPress ( VkI )
END IF
END IF
'VK(VKi).held = 0
VkI = 0
END IF
END IF
rt = VkByRole ( "ROOT" )
IF mb THEN
IF VkI THEN
canMove = 0
IF VK ( rt ) . locked < > 0 OR VK ( VkI ) . internal = 1 THEN canMove = 1
IF canMove = 1 THEN
'calculate distance in units from mouse down location to current location
nx = VKoldX + CINT ( ( mx - mDownX ) / VkUnitSize )
ny = VKoldY - CINT ( ( my - mDownY ) / VkUnitSize / VkUnitStepY ) * VkUnitStepY
distX = ABS ( VKoldX - nx )
distY = ABS ( VKoldY - ny )
IF distY > distX THEN dist = distY ELSE dist = distX
IF dist > = VkUnitStepY THEN
IF VK ( rt ) . locked < > 0 OR VK ( VkI ) . internal = 1 THEN
VKdragging = -1
'VK(VKi).held = 0
IF VK ( VkI ) . parent < > 0 AND VK ( VkI ) . internal < > 0 THEN
p = VK ( VkI ) . parent
mDownX = mDownX + ( VK ( VkI ) . x - VK ( p ) . x ) * VkUnitSize
mDownY = mDownY + ( VK ( p ) . y - VK ( VkI ) . y ) * VkUnitSize
VkI = p
END IF
END IF
END IF
END IF 'canmove=1
'dpad
IF canMove = 0 THEN
IF VK ( rt ) . locked = 0 AND VK ( VkI ) . event . keydown = -1 THEN
'dpad
VKdragging = -1
END IF
END IF
IF VKdragging THEN
IF VK ( rt ) . locked = 0 AND VK ( VkI ) . event . keydown = -1 THEN
dpadx = mx - mDownX '(VK(VkI).x * VkUnitSize + VkUnitSize / 2)
dpady = my - mDownY ' (sy - VK(VkI).y * VkUnitSize - VkUnitSize / 2)
dpadx = dpadx / ( VkUnitSize * VkDefaultWidth * 0.9 )
dpady = dpady / ( VkUnitSize * VkDefaultWidth * 0.9 )
'normalize if greater than 1 unit
l = SQR ( dpadx * dpadx + dpady * dpady )
IF l > 1 THEN
dpadx = dpadx / l
dpady = dpady / l
END IF
VkUpdateDPAD VkI , dpadx , dpady
'convert dpad value relative to 1/0
ELSE
'prevent off-screen drag
IF nx < 0 THEN nx = 0
IF ny < 0 THEN ny = 0
'prevent covering of other (non-internal) keys
ox = VK ( VkI ) . x
oy = VK ( VkI ) . y
oldOffsetX = VK ( VkI ) . offsetX
oldOffsetY = VK ( VkI ) . offsetY
IF ox < > nx OR oy < > ny THEN
sgnx = SGN ( nx - ox ) : IF sgnx = 0 THEN sgnx = 1
sgny = SGN ( ny - oy ) * VkUnitStepY: IF sgny = 0 THEN sgny = VkUnitStepY
bestDist = 10000
FOR ix = ox TO nx STEP sgnx
FOR iy = oy TO ny STEP sgny
blocked = 0
IF VK ( VkI ) . event . keydown < > -2 AND VK ( VkI ) . internal = 0 THEN
nw = VK ( VkI ) . w
FOR i = 1 TO VkLast
IF VK ( i ) . internal = 0 AND VK ( i ) . active AND i < > VkI AND VK ( i ) . event . keydown < > -2 THEN
y = VK ( i ) . y: x = VK ( i ) . x: w = VK ( i ) . w
IF iy = y THEN 'same row
ok = 0
IF ix > = x + w THEN ok = 1
IF ix + nw < = x THEN ok = 1
IF ok = 0 THEN blocked = 1
END IF
END IF
NEXT
END IF
IF blocked = 0 THEN
dist = ABS ( nx - ix ) + ABS ( ny - iy )
IF dist < bestDist THEN
bestDist = dist
IF VK ( VkI ) . parent THEN
VK ( VkI ) . offsetX = oldOffsetX + ( ix - ox )
VK ( VkI ) . offsetY = oldOffsetY + ( iy - oy )
END IF
VK ( VkI ) . x = ix
VK ( VkI ) . y = iy
VkReDraw = 1
END IF
END IF
NEXT
NEXT
END IF
END IF
END IF
END IF
END IF
LOOP UNTIL mEvent = 0
'_DISPLAY
'_LIMIT 30
'k$ = inkey$
'k$ = ""
_DEST subOldDest
_SOURCE subOldSource
if VkExiting = 2 then
VkExiting = 0
VkExited = 1
end if
END SUB
FUNCTION VkColTex& ( col& )
i& = _NEWIMAGE ( 1 , 1 , 32 )
oldDest& = _DEST
_DEST i&
_DONTBLEND
CLS , col&
_BLEND
_DEST oldDest&
VkColTex& = _COPYIMAGE ( i& , 33 )
_FREEIMAGE i&
END FUNCTION
SUB VkUpdateDPAD ( i , x , y )
VkReDraw = 1
ox = VK ( i ) . dpad . x
oy = VK ( i ) . dpad . y
minDist = 0.35 'diagonal max. dist is ~7
odx = VK ( i ) . dpad . dx
ody = VK ( i ) . dpad . dy
dx = 0
IF x < = - minDist THEN dx = -1
IF x > = minDist THEN dx = 1
dy = 0
IF y < = - minDist THEN dy = -1
IF y > = minDist THEN dy = 1
'hardcoded dpad keys
VK ( i ) . dpad . left . keydown = VK_KEY_LEFT
VK ( i ) . dpad . right . keydown = VK_KEY_RIGHT
VK ( i ) . dpad . up . keydown = VK_KEY_UP
VK ( i ) . dpad . down . keydown = VK_KEY_DOWN
IF dx < > odx THEN
IF odx = -1 THEN keyup VK ( i ) . dpad . left . keydown
IF odx = 1 THEN keyup VK ( i ) . dpad . right . keydown
IF dx = -1 THEN keydown VK ( i ) . dpad . left . keydown: VK ( i ) . dpad . lastKeyDx = dx: VK ( i ) . dpad . lastKeyDy = 0
IF dx = 1 THEN keydown VK ( i ) . dpad . right . keydown: VK ( i ) . dpad . lastKeyDx = dx: VK ( i ) . dpad . lastKeyDy = 0
END IF
IF dy < > ody THEN
IF ody = -1 THEN keyup VK ( i ) . dpad . up . keydown
IF ody = 1 THEN keyup VK ( i ) . dpad . down . keydown
IF dy = -1 THEN keydown VK ( i ) . dpad . up . keydown: VK ( i ) . dpad . lastKeyDy = dy: VK ( i ) . dpad . lastKeyDx = 0
IF dy = 1 THEN keydown VK ( i ) . dpad . down . keydown: VK ( i ) . dpad . lastKeyDy = dy: VK ( i ) . dpad . lastKeyDx = 0
END IF
'strongest direction must have been represented by last known keydown event fired by dpad
IF dx < > 0 OR dy < > 0 THEN 'has direction
bestDx = 0 : bestDy = 0
IF ABS ( x ) > ABS ( y ) THEN
bestDx = SGN ( x )
ELSE
bestDy = SGN ( y )
END IF
IF bestDx < > VK ( i ) . dpad . lastKeyDx AND bestDx < > 0 THEN
dx = bestDx
IF dx = -1 THEN keydown VK ( i ) . dpad . left . keydown: VK ( i ) . dpad . lastKeyDx = dx: VK ( i ) . dpad . lastKeyDy = 0
IF dx = 1 THEN keydown VK ( i ) . dpad . right . keydown: VK ( i ) . dpad . lastKeyDx = dx: VK ( i ) . dpad . lastKeyDy = 0
ELSE
IF bestDy < > VK ( i ) . dpad . lastKeyDy AND bestDy < > 0 THEN
dy = bestDy
IF dy = -1 THEN keydown VK ( i ) . dpad . up . keydown: VK ( i ) . dpad . lastKeyDy = dy: VK ( i ) . dpad . lastKeyDx = 0
IF dy = 1 THEN keydown VK ( i ) . dpad . down . keydown: VK ( i ) . dpad . lastKeyDy = dy: VK ( i ) . dpad . lastKeyDx = 0
END IF
END IF
END IF
VK ( i ) . dpad . dx = dx
VK ( i ) . dpad . dy = dy
VK ( i ) . dpad . x = x
VK ( i ) . dpad . y = y
END SUB
SUB VkReLabel ( i , label$ )
VkReDraw = 1
VK ( i ) . label = label$
VK ( i ) . reDraw = 1
END SUB
SUB VkReLabelShifted ( i , label$ )
VkReDraw = 1
VK ( i ) . shiftedLabel = label$
VK ( i ) . reDraw = 1
END SUB
SUB VkAddKeyName ( keyName AS STRING , keyCode AS LONG )
value = QB_NODE_new ( QB_NODE_TYPE_VALUE , 0 )
QB_NODE_setLabel_format value , QB_STR_new ( keyName ) , QB_NODE_FORMAT_STR
QB_NODE_setValue_format value , keyCode , QB_NODE_FORMAT_LONG
QB_NODE_assign VkKeyCodeLookup , value
value = QB_NODE_new ( QB_NODE_TYPE_VALUE , 0 )
QB_NODE_setLabel_format value , keyCode , QB_NODE_FORMAT_LONG
QB_NODE_setValue_format value , QB_STR_new ( keyName ) , QB_NODE_FORMAT_STR
QB_NODE_assign VkKeyNameLookup , value
END SUB
SUB VkAddKeyNames
VkKeyNameLookup = QB_NODE_newDictionary
VkKeyCodeLookup = QB_NODE_newDictionary
VkAddKeyName "KEY_PAUSE" , 100019
VkAddKeyName "KEY_NUMLOCK" , 100300
VkAddKeyName "KEY_CAPSLOCK" , 100301
VkAddKeyName "KEY_SCROLLOCK" , 100302
VkAddKeyName "KEY_RSHIFT" , 100303
VkAddKeyName "KEY_LSHIFT" , 100304
VkAddKeyName "KEY_RCTRL" , 100305
VkAddKeyName "KEY_LCTRL" , 100306
VkAddKeyName "KEY_RALT" , 100307
VkAddKeyName "KEY_LALT" , 100308
VkAddKeyName "KEY_RMETA" , 100309
VkAddKeyName "KEY_LMETA" , 100310
VkAddKeyName "KEY_LSUPER" , 100311
VkAddKeyName "KEY_RSUPER" , 100312
VkAddKeyName "KEY_MODE" , 100313
VkAddKeyName "KEY_COMPOSE" , 100314
VkAddKeyName "KEY_HELP" , 100315
VkAddKeyName "KEY_PRINT" , 100316
VkAddKeyName "KEY_SYSREQ" , 100317
VkAddKeyName "KEY_BREAK" , 100318
VkAddKeyName "KEY_MENU" , 100319
VkAddKeyName "KEY_POWER" , 100320
VkAddKeyName "KEY_EURO" , 100321
VkAddKeyName "KEY_UNDO" , 100322
VkAddKeyName "KEY_KP0" , 100256
VkAddKeyName "KEY_KP1" , 100257
VkAddKeyName "KEY_KP2" , 100258
VkAddKeyName "KEY_KP3" , 100259
VkAddKeyName "KEY_KP4" , 100260
VkAddKeyName "KEY_KP5" , 100261
VkAddKeyName "KEY_KP6" , 100262
VkAddKeyName "KEY_KP7" , 100263
VkAddKeyName "KEY_KP8" , 100264
VkAddKeyName "KEY_KP9" , 100265
VkAddKeyName "KEY_KP_PERIOD" , 100266
VkAddKeyName "KEY_KP_DIVIDE" , 100267
VkAddKeyName "KEY_KP_MULTIPLY" , 100268
VkAddKeyName "KEY_KP_MINUS" , 100269
VkAddKeyName "KEY_KP_PLUS" , 100270
VkAddKeyName "KEY_KP_ENTER" , 100271
VkAddKeyName "KEY_KP_INSERT" , 200000
VkAddKeyName "KEY_KP_END" , 200001
VkAddKeyName "KEY_KP_DOWN" , 200002
VkAddKeyName "KEY_KP_PAGE_DOWN" , 200003
VkAddKeyName "KEY_KP_LEFT" , 200004
VkAddKeyName "KEY_KP_MIDDLE" , 200005
VkAddKeyName "KEY_KP_RIGHT" , 200006
VkAddKeyName "KEY_KP_HOME" , 200007
VkAddKeyName "KEY_KP_UP" , 200008
VkAddKeyName "KEY_KP_PAGE_UP" , 200009
VkAddKeyName "KEY_KP_DELETE" , 200010
VkAddKeyName "KEY_SCROLL_LOCK_MODE" , 200011
VkAddKeyName "KEY_INSERT_MODE" , 200012
VkAddKeyName "KEY_F1" , 15104
VkAddKeyName "KEY_F2" , 15360
VkAddKeyName "KEY_F3" , 15616
VkAddKeyName "KEY_F4" , 15872
VkAddKeyName "KEY_F5" , 16128
VkAddKeyName "KEY_F6" , 16384
VkAddKeyName "KEY_F7" , 16640
VkAddKeyName "KEY_F8" , 16896
VkAddKeyName "KEY_F9" , 17152
VkAddKeyName "KEY_F10" , 17408
VkAddKeyName "KEY_F11" , 34048
VkAddKeyName "KEY_F12" , 34304
VkAddKeyName "KEY_INSERT" , 20992
VkAddKeyName "KEY_DELETE" , 21248
VkAddKeyName "KEY_HOME" , 18176
VkAddKeyName "KEY_END" , 20224
VkAddKeyName "KEY_PAGE_UP" , 18688
VkAddKeyName "KEY_PAGE_DOWN" , 20736
VkAddKeyName "KEY_UP" , 18432
VkAddKeyName "KEY_DOWN" , 20480
VkAddKeyName "KEY_LEFT" , 19200
VkAddKeyName "KEY_RIGHT" , 19712
VkAddKeyName "KEY_BACKSPACE" , 8
VkAddKeyName "KEY_TAB" , 9
VkAddKeyName "KEY_ENTER" , 13
VkAddKeyName "KEY_ESCAPE" , 27
VkAddKeyName "KEY_SPACE" , 32
VkAddKeyName "KEY_EXCLAMATION" , 33
VkAddKeyName "KEY_QUOTE" , 34
VkAddKeyName "KEY_HASH" , 35
VkAddKeyName "KEY_DOLLAR" , 36
VkAddKeyName "KEY_PERCENT" , 37
VkAddKeyName "KEY_AND" , 38
VkAddKeyName "KEY_APOSTROPHE" , 39
VkAddKeyName "KEY_OPEN_BRACKET" , 40
VkAddKeyName "KEY_CLOSE_BRACKET" , 41
VkAddKeyName "KEY_STAR" , 42
VkAddKeyName "KEY_PLUS" , 43
VkAddKeyName "KEY_COMMA" , 44
VkAddKeyName "KEY_MINUS" , 45
VkAddKeyName "KEY_DOT" , 46
VkAddKeyName "KEY_FORWARD_SLASH" , 47
VkAddKeyName "KEY_0" , 48
VkAddKeyName "KEY_1" , 49
VkAddKeyName "KEY_2" , 50
VkAddKeyName "KEY_3" , 51
VkAddKeyName "KEY_4" , 52
VkAddKeyName "KEY_5" , 53
VkAddKeyName "KEY_6" , 54
VkAddKeyName "KEY_7" , 55
VkAddKeyName "KEY_8" , 56
VkAddKeyName "KEY_9" , 57
VkAddKeyName "KEY_COLON" , 58
VkAddKeyName "KEY_SEMICOLON" , 59
VkAddKeyName "KEY_LESS_THAN" , 60
VkAddKeyName "KEY_EQUAL" , 61
VkAddKeyName "KEY_GREATER_THAN" , 62
VkAddKeyName "KEY_QUESTION" , 63
VkAddKeyName "KEY_AT" , 64
VkAddKeyName "KEY_A" , 65
VkAddKeyName "KEY_B" , 66
VkAddKeyName "KEY_C" , 67
VkAddKeyName "KEY_D" , 68
VkAddKeyName "KEY_E" , 69
VkAddKeyName "KEY_F" , 70
VkAddKeyName "KEY_G" , 71
VkAddKeyName "KEY_H" , 72
VkAddKeyName "KEY_I" , 73
VkAddKeyName "KEY_J" , 74
VkAddKeyName "KEY_K" , 75
VkAddKeyName "KEY_L" , 76
VkAddKeyName "KEY_M" , 77
VkAddKeyName "KEY_N" , 78
VkAddKeyName "KEY_O" , 79
VkAddKeyName "KEY_P" , 80
VkAddKeyName "KEY_Q" , 81
VkAddKeyName "KEY_R" , 82
VkAddKeyName "KEY_S" , 83
VkAddKeyName "KEY_T" , 84
VkAddKeyName "KEY_U" , 85
VkAddKeyName "KEY_V" , 86
VkAddKeyName "KEY_W" , 87
VkAddKeyName "KEY_X" , 88
VkAddKeyName "KEY_Y" , 89
VkAddKeyName "KEY_Z" , 90
VkAddKeyName "KEY_UCASE_A" , 65
VkAddKeyName "KEY_UCASE_B" , 66
VkAddKeyName "KEY_UCASE_C" , 67
VkAddKeyName "KEY_UCASE_D" , 68
VkAddKeyName "KEY_UCASE_E" , 69
VkAddKeyName "KEY_UCASE_F" , 70
VkAddKeyName "KEY_UCASE_G" , 71
VkAddKeyName "KEY_UCASE_H" , 72
VkAddKeyName "KEY_UCASE_I" , 73
VkAddKeyName "KEY_UCASE_J" , 74
VkAddKeyName "KEY_UCASE_K" , 75
VkAddKeyName "KEY_UCASE_L" , 76
VkAddKeyName "KEY_UCASE_M" , 77
VkAddKeyName "KEY_UCASE_N" , 78
VkAddKeyName "KEY_UCASE_O" , 79
VkAddKeyName "KEY_UCASE_P" , 80
VkAddKeyName "KEY_UCASE_Q" , 81
VkAddKeyName "KEY_UCASE_R" , 82
VkAddKeyName "KEY_UCASE_S" , 83
VkAddKeyName "KEY_UCASE_T" , 84
VkAddKeyName "KEY_UCASE_U" , 85
VkAddKeyName "KEY_UCASE_V" , 86
VkAddKeyName "KEY_UCASE_W" , 87
VkAddKeyName "KEY_UCASE_X" , 88
VkAddKeyName "KEY_UCASE_Y" , 89
VkAddKeyName "KEY_UCASE_Z" , 90
VkAddKeyName "KEY_OPEN_BRACKET_SQUARE" , 91
VkAddKeyName "KEY_BACK_SLASH" , 92
VkAddKeyName "KEY_CLOSE_BRACKET_SQUARE" , 93
VkAddKeyName "KEY_CARET" , 94
VkAddKeyName "KEY_UNDERSCORE" , 95
VkAddKeyName "KEY_REVERSE_APOSTROPHE" , 96
VkAddKeyName "KEY_LCASE_A" , 97
VkAddKeyName "KEY_LCASE_B" , 98
VkAddKeyName "KEY_LCASE_C" , 99
VkAddKeyName "KEY_LCASE_D" , 100
VkAddKeyName "KEY_LCASE_E" , 101
VkAddKeyName "KEY_LCASE_F" , 102
VkAddKeyName "KEY_LCASE_G" , 103
VkAddKeyName "KEY_LCASE_H" , 104
VkAddKeyName "KEY_LCASE_I" , 105
VkAddKeyName "KEY_LCASE_J" , 106
VkAddKeyName "KEY_LCASE_K" , 107
VkAddKeyName "KEY_LCASE_L" , 108
VkAddKeyName "KEY_LCASE_M" , 109
VkAddKeyName "KEY_LCASE_N" , 110
VkAddKeyName "KEY_LCASE_O" , 111
VkAddKeyName "KEY_LCASE_P" , 112
VkAddKeyName "KEY_LCASE_Q" , 113
VkAddKeyName "KEY_LCASE_R" , 114
VkAddKeyName "KEY_LCASE_S" , 115
VkAddKeyName "KEY_LCASE_T" , 116
VkAddKeyName "KEY_LCASE_U" , 117
VkAddKeyName "KEY_LCASE_V" , 118
VkAddKeyName "KEY_LCASE_W" , 119
VkAddKeyName "KEY_LCASE_X" , 120
VkAddKeyName "KEY_LCASE_Y" , 121
VkAddKeyName "KEY_LCASE_Z" , 122
VkAddKeyName "KEY_OPEN_BRACKET_CURLY" , 123
VkAddKeyName "KEY_VERTICAL_BAR" , 124
VkAddKeyName "KEY_CLOSE_BRACKET_CURLY" , 125
VkAddKeyName "KEY_TILDE" , 126
VkAddKeyName "KEY_BACKSPACE_ALTERNATE" , 127
END SUB
FUNCTION VkGetKeyName$ ( keyCode AS LONG )
VkGetKeyName$ = QB_STR_long ( keyCode )
DIM VkChild AS LONG
DIM VkI AS LONG
DO WHILE QB_NODE_eachWithLabel_format ( VkChild , VkKeyNameLookup , keyCode , QB_NODE_FORMAT_LONG , VkI )
VkGetKeyName$ = QB_NODE_value ( VkChild )
EXIT FUNCTION
LOOP
END FUNCTION
FUNCTION VkGetKeyCode& ( keyName AS STRING )
DIM i AS LONG
i = QB_NODE_withLabel ( VkKeyCodeLookup , keyName )
IF i THEN
VkGetKeyCode& = VAL ( QB_NODE_value ( i ) )
ELSE
VkGetKeyCode& = VAL ( keyName )
END IF
END FUNCTION
SUB VkSaveKeys ( parentNode AS LONG , parentKey AS LONG )
FOR i = 1 TO VkLast
IF VK ( i ) . internal = 0 AND VK ( i ) . active < > 0 AND VK ( i ) . parent = parentKey THEN
thisKey = QB_NODE_newDictionary
QB_NODE_assign parentNode , thisKey
'get type
keyType$ = "key"
IF VK ( i ) . event . keydown = -1 THEN
keyType$ = "joystick"
END IF
IF VK ( i ) . event . keydown = -2 THEN
keyType$ = "keySet"
END IF
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel ( "type" , keyType$ )
IF parentKey = 0 THEN
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_long ( "x" , VK ( i ) . x )
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_long ( "y" , VK ( i ) . y )
ELSE
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_long ( "offsetX" , VK ( i ) . offsetX )
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_long ( "offsetY" , VK ( i ) . offsetY )
END IF
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_long ( "width" , VK ( i ) . w )
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_long ( "height" , VK ( i ) . h )
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel ( "label" , RTRIM$ ( VK ( i ) . label ) )
events = QB_NODE_newDictionary: QB_NODE_setLabel events , "events"
IF keyType$ = "key" THEN
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_bool ( "locks" , VK ( i ) . locks )
QB_NODE_assign thisKey , QB_NODE_newValueWithLabel_bool ( "lockIsTemporary" , VK ( i ) . lockIsTemporary )
event = QB_NODE_newDictionary: QB_NODE_setLabel event , "keydown" : QB_NODE_assign events , event
QB_NODE_assign event , QB_NODE_newValueWithLabel ( "keyCode" , VkGetKeyName ( VK ( i ) . event . keydown ) )
IF VK ( i ) . hasShiftedEvent THEN
event = QB_NODE_newDictionary: QB_NODE_setLabel event , "keydownWithShift" : QB_NODE_assign events , event
QB_NODE_assign event , QB_NODE_newValueWithLabel ( "keyCode" , VkGetKeyName ( VK ( i ) . shiftedEvent . keydown ) )
QB_NODE_assign event , QB_NODE_newValueWithLabel ( "label" , RTRIM$ ( VK ( i ) . shiftedLabel ) )
END IF
END IF
IF keyType$ = "joystick" THEN
'hardcode keys
VK ( i ) . dpad . left . keydown = VK_KEY_LEFT
VK ( i ) . dpad . right . keydown = VK_KEY_RIGHT
VK ( i ) . dpad . up . keydown = VK_KEY_UP
VK ( i ) . dpad . down . keydown = VK_KEY_DOWN
event = QB_NODE_newDictionary: QB_NODE_setLabel event , "up" : QB_NODE_assign events , event
QB_NODE_assign event , QB_NODE_newValueWithLabel ( "keyCode" , VkGetKeyName ( VK ( i ) . dpad . up . keydown ) )
event = QB_NODE_newDictionary: QB_NODE_setLabel event , "down" : QB_NODE_assign events , event
QB_NODE_assign event , QB_NODE_newValueWithLabel ( "keyCode" , VkGetKeyName ( VK ( i ) . dpad . down . keydown ) )
event = QB_NODE_newDictionary: QB_NODE_setLabel event , "left" : QB_NODE_assign events , event
QB_NODE_assign event , QB_NODE_newValueWithLabel ( "keyCode" , VkGetKeyName ( VK ( i ) . dpad . left . keydown ) )
event = QB_NODE_newDictionary: QB_NODE_setLabel event , "right" : QB_NODE_assign events , event
QB_NODE_assign event , QB_NODE_newValueWithLabel ( "keyCode" , VkGetKeyName ( VK ( i ) . dpad . right . keydown ) )
END IF
IF keyType$ = "keySet" THEN
END IF
IF QB_NODE_count ( events ) > 0 THEN
QB_NODE_assign thisKey , events
ELSE
QB_NODE_destroy events
END IF
childKeys = QB_NODE_newList: QB_NODE_setLabel childKeys , "childKeys"
VkSaveKeys childKeys , i
IF QB_NODE_count ( childKeys ) > 0 THEN
QB_NODE_assign thisKey , childKeys
ELSE
QB_NODE_destroy childKeys
END IF
END IF
NEXT
END SUB
SUB VkSave
root = QB_NODE_newDictionary
QB_NODE_assign root , QB_NODE_newValueWithLabel_long ( "width" , VkWidthInUnits )
keys = QB_NODE_newList: QB_NODE_setLabel keys , "keys" : QB_NODE_assign root , keys
VkSaveKeys keys , 0
json$ = QB_NODESET_serialize ( root , "json" )
QB_NODE_destroy root
fh = FREEFILE
OPEN appRootPath$ + "virtual_keyboard_layout_current.txt" FOR OUTPUT AS # fh
PRINT # fh , json$
CLOSE # fh
END SUB
SUB VkLoadKeys ( parentNode AS LONG , parentKey AS LONG )
DIM iterator AS LONG
DIM keyNode AS LONG
DO WHILE QB_NODE_each ( keyNode , parentNode , iterator )
DIM events AS LONG
DIM event AS LONG
events = QB_NODE_withLabel ( keyNode , "events" )
keyType$ = QB_NODE_valueOfLabel ( keyNode , "type" )
i = VkNew
VK ( i ) . role = "USER"
VK ( i ) . parent = parentKey
IF parentKey THEN
VK ( i ) . offsetX = QB_NODE_valueOfLabel_long ( keyNode , "offsetX" )
VK ( i ) . offsetY = QB_NODE_valueOfLabel_long ( keyNode , "offsetY" )
ELSE
VK ( i ) . x = QB_NODE_valueOfLabel_long ( keyNode , "x" )
VK ( i ) . y = QB_NODE_valueOfLabel_long ( keyNode , "y" )
END IF
VK ( i ) . w = QB_NODE_valueOfLabel_long ( keyNode , "width" )
VK ( i ) . h = QB_NODE_valueOfLabel_long ( keyNode , "height" )
VK ( i ) . label = QB_NODE_valueOfLabel ( keyNode , "label" )
IF keyType$ = "key" THEN
VK ( i ) . locks = QB_NODE_valueOfLabel_bool ( keyNode , "locks" )
VK ( i ) . lockIsTemporary = QB_NODE_valueOfLabel_bool ( keyNode , "lockIsTemporary" )
VK ( i ) . event . keydown = VkGetKeyCode& ( QB_NODE_valueOfLabel ( QB_NODE_withLabel ( events , "keydown" ) , "keyCode" ) )
shiftedEvent = QB_NODE_withLabel ( events , "keydownWithShift" )
IF shiftedEvent THEN
VK ( i ) . hasShiftedEvent = 1
VK ( i ) . shiftedEvent . keydown = VkGetKeyCode& ( QB_NODE_valueOfLabel ( shiftedEvent , "keyCode" ) )
VK ( i ) . shiftedLabel = QB_NODE_valueOfLabel ( shiftedEvent , "label" )
END IF
END IF
IF keyType$ = "keySet" THEN
VK ( i ) . event . keydown = -2
VkLoadKeys QB_NODE_withLabel ( keyNode , "childKeys" ) , i
END IF
IF keyType$ = "joystick" THEN
VK ( i ) . event . keydown = -1
VK ( i ) . dpad . left . keydown = VkGetKeyCode& ( QB_NODE_valueOfLabel ( QB_NODE_withLabel ( events , "left" ) , "keyCode" ) )
VK ( i ) . dpad . right . keydown = VkGetKeyCode& ( QB_NODE_valueOfLabel ( QB_NODE_withLabel ( events , "right" ) , "keyCode" ) )
VK ( i ) . dpad . up . keydown = VkGetKeyCode& ( QB_NODE_valueOfLabel ( QB_NODE_withLabel ( events , "up" ) , "keyCode" ) )
VK ( i ) . dpad . down . keydown = VkGetKeyCode& ( QB_NODE_valueOfLabel ( QB_NODE_withLabel ( events , "down" ) , "keyCode" ) )
END IF
LOOP
END SUB
FUNCTION VkGetQuotedString$ ( a$ )
a2$ = SPACE$ ( LEN ( a$ ) )
i2 = 0
FOR i = 1 TO LEN ( a$ )
a2 = a
a = ASC ( a$ , i )
IF a2 = 92 AND a = 113 THEN
ASC ( a2$ , i2 ) = 34
ELSE
i2 = i2 + 1
ASC ( a2$ , i2 ) = a
END IF
NEXT
a2$ = LEFT$ ( a2$ , i2 )
VkGetQuotedString$ = a2$
END FUNCTION
SUB VkLoad
VkFile$ = ""
if _FILEEXISTS ( appRootPath$ + "virtual_keyboard_layout_default.txt" ) then VkFile$ = appRootPath$ + "virtual_keyboard_layout_default.txt"
if _FILEEXISTS ( appRootPath$ + "virtual_keyboard_layout_current.txt" ) then VkFile$ = appRootPath$ + "virtual_keyboard_layout_current.txt"
if VkFile$ < > "" then
fh = FREEFILE
OPEN VkFile$ FOR INPUT AS # fh
LINE INPUT # fh , json$
CLOSE # fh
root = QB_NODESET_deserialize ( json$ , "json" )
DIM oldVkWidthInUnits AS LONG
oldVkWidthInUnits = VkWidthInUnits
VkWidthInUnits = 90
DIM rootValueNode AS LONG
rootValueNode = QB_NODE_withLabel ( root , "width" )
if rootValueNode then VkWidthInUnits = QB_NODE_valueOfLabel_long ( root , "width" )
if VkWidthInUnits < > oldVkWidthInUnits then
FOR i3 = 1 TO VkLast
IF VK ( i3 ) . active THEN
VK ( i3 ) . reDraw = 1
END IF
NEXT
VkReset = 1
END IF
VkLoadKeys QB_NODESET_node ( QB_NODESET_label_equal ( QB_NODESET_children ( root ) , "keys" ) ) , 0
QB_NODE_destroy root
end if
END SUB
FUNCTION VkShiftInEffect
shiftInEffect = 0
'IF _KEYDOWN(VK_KEY_LSHIFT) OR _KEYDOWN(VK_KEY_RSHIFT) THEN
' shiftInEffect = 1
'END IF
shiftLockInEffect = 0
FOR i = 1 TO VkLast
IF VK ( i ) . active THEN
IF VK ( i ) . internal = 0 THEN
'is this a caps lock or shift key?
'is it active?
IF VK ( i ) . event . keydown = VK_KEY_CAPSLOCK THEN
IF VK ( i ) . held < > 0 THEN
shiftLockInEffect = 1
END IF
END IF
END IF
END IF
NEXT
shiftKeyHeld = 0
FOR i = 1 TO VkLast
IF VK ( i ) . active THEN
IF VK ( i ) . internal = 0 THEN
'is this a caps lock or shift key?
'is it active?
IF VK ( i ) . event . keydown = VK_KEY_LSHIFT OR VK ( i ) . event . keydown = VK_KEY_RSHIFT THEN
IF VK ( i ) . held < > 0 THEN
shiftKeyHeld = 1
END IF
END IF
END IF
END IF
NEXT
IF shiftLockInEffect + shiftKeyHeld = 1 THEN shiftInEffect = 1
IF VkAddShiftedKey = 1 THEN shiftInEffect = 1
VkShiftInEffect = shiftInEffect
END FUNCTION
SUB VkGetMouse ( mx AS LONG , my AS LONG , mb AS LONG )
'DIM SHARED VkReg AS VkRegTypeX
VkReg . ax = 3
CALL INTERRUPT ( & H33 , VkReg , VkReg )
mb = VkReg . bx AND 1
mx = VkReg . cx
my = VkReg . dx
END SUB
FUNCTION VkFindFont& ( idealSize AS LONG )
FOR diff = 0 TO 1000
FOR negative = 0 TO 1
IF negative THEN
size = idealSize - diff
ELSE
size = idealSize + diff \ 2 'increase of size is less desirable that decrease of size
END IF
IF size > = 0 AND size < = UBOUND ( vkfontAllow ) THEN
IF vkFontAllow ( size ) THEN
if vkFonts ( size ) = 0 then vkFonts ( size ) = _LOADFONT ( appRootPath$ + "cyberbit.ttf" , size )
if vkFonts ( size ) = 0 then 'font failed to load, so use inbuilt font instead
vkFonts ( size ) = 16
if size < 16 then vkFonts ( size ) = 8
end if
VkFindFont& = vkFonts ( size )
EXIT FUNCTION
END IF
END IF
NEXT
NEXT
END FUNCTION