summaryrefslogtreecommitdiff
path: root/xmake/core/ui/program.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2017-12-16 00:57:23 +0800
committerruki <[email protected]>2017-12-15 23:44:19 +0800
commite5ed897840214b66fd746292fff15c56606d3251 (patch)
tree6a5820bfcb1acf95536b673cd79587aff198dab5 /xmake/core/ui/program.lua
parentd81f894af27987981ef3fe39e013ad3f1fadfbcf (diff)
add event to ui
Diffstat (limited to 'xmake/core/ui/program.lua')
-rw-r--r--xmake/core/ui/program.lua154
1 files changed, 154 insertions, 0 deletions
diff --git a/xmake/core/ui/program.lua b/xmake/core/ui/program.lua
index 75c08fc79..af3cb09bf 100644
--- a/xmake/core/ui/program.lua
+++ b/xmake/core/ui/program.lua
@@ -30,6 +30,7 @@ $Id: program.lua 18 2007-06-21 20:43:52Z tngd $
-- load modules
local rect = require("ui/rect")
local group = require("ui/group")
+local event = require("ui/event")
local curses = require("ui/curses")
-- define module
@@ -118,6 +119,28 @@ function program:argv()
return self._ARGV
end
+-- get the current event
+function program:event()
+
+ -- get input key
+ local key_code, key_name, key_meta = self:_input_key()
+ if key_code then
+ if key_name == "Resize" or key_name == "CtrlL" then
+ self:change_bounds(Rect{0, 0, curses.columns(), curses.lines()})
+ self:refresh()
+ elseif key_name == "Refresh" then
+ self:refresh()
+ else
+ return event.keyboard{key_code, key_name, key_meta}
+ end
+ end
+end
+
+-- put an event to view
+function program:event_put(e)
+ -- TODO
+end
+
-- run program loop
function program:loop(argv)
@@ -128,5 +151,136 @@ function program:loop(argv)
self:execute()
end
+-- get key map
+function program:_key_map()
+ if not self._KEYMAP then
+ self._KEYMAP =
+ {
+ [ 1] = "CtrlA", [ 2] = "CtrlB", [ 3] = "CtrlC",
+ [ 4] = "CtrlD", [ 5] = "CtrlE", [ 6] = "CtrlF",
+ [ 7] = "CtrlG", [ 8] = "CtrlH", [ 9] = "CtrlI",
+ [10] = "CtrlJ", [11] = "CtrlK", [12] = "CtrlL",
+ [13] = "CtrlM", [14] = "CtrlN", [15] = "CtrlO",
+ [16] = "CtrlP", [17] = "CtrlQ", [18] = "CtrlR",
+ [19] = "CtrlS", [20] = "CtrlT", [21] = "CtrlU",
+ [22] = "CtrlV", [23] = "CtrlW", [24] = "CtrlX",
+ [25] = "CtrlY", [26] = "CtrlZ",
+
+ [ 8] = "Backspace",
+ [ 9] = "Tab",
+ [ 10] = "Enter",
+ [ 13] = "Enter",
+ [ 27] = "Esc",
+ [ 31] = "CtrlBackspace",
+ [127] = "Backspace",
+
+ [curses.KEY_DOWN ] = "Down",
+ [curses.KEY_UP ] = "Up",
+ [curses.KEY_LEFT ] = "Left",
+ [curses.KEY_RIGHT ] = "Right",
+ [curses.KEY_HOME ] = "Home",
+ [curses.KEY_END ] = "End",
+ [curses.KEY_NPAGE ] = "PageDown",
+ [curses.KEY_PPAGE ] = "PageUp",
+ [curses.KEY_IC ] = "Insert",
+ [curses.KEY_DC ] = "Delete",
+ [curses.KEY_BACKSPACE ] = "Backspace",
+ [curses.KEY_F1 ] = "F1",
+ [curses.KEY_F2 ] = "F2",
+ [curses.KEY_F3 ] = "F3",
+ [curses.KEY_F4 ] = "F4",
+ [curses.KEY_F5 ] = "F5",
+ [curses.KEY_F6 ] = "F6",
+ [curses.KEY_F7 ] = "F7",
+ [curses.KEY_F8 ] = "F8",
+ [curses.KEY_F9 ] = "F9",
+ [curses.KEY_F10 ] = "F10",
+ [curses.KEY_F11 ] = "F11",
+ [curses.KEY_F12 ] = "F12",
+
+ [curses.KEY_RESIZE ] = "Resize",
+ [curses.KEY_REFRESH ] = "Refresh",
+
+ [curses.KEY_BTAB ] = "ShiftTab",
+ [curses.KEY_SDC ] = "ShiftDelete",
+ [curses.KEY_SIC ] = "ShiftInsert",
+ [curses.KEY_SEND ] = "ShiftEnd",
+ [curses.KEY_SHOME ] = "ShiftHome",
+ [curses.KEY_SLEFT ] = "ShiftLeft",
+ [curses.KEY_SRIGHT ] = "ShiftRight",
+ }
+ end
+ return self._KEYMAP
+end
+
+-- get input key
+function program:_input_key()
+
+ -- get main window
+ local main_window = self:main_window()
+
+ -- get input character
+ local ch = main_window:getch()
+ if not ch then
+ return
+ end
+
+ -- this is the time limit in ms within Esc-key sequences are detected as
+ -- Alt-letter sequences. useful when we can't generate Alt-letter sequences
+ -- directly. sometimes this pause may be longer than expected since the
+ -- curses driver may also pause waiting for another key (ncurses-5.3)
+ local esc_delay = 400
+
+ -- get key map
+ local key_map = self:_key_map()
+
+ -- is alt?
+ local alt = ch == 27
+ if alt then
+
+ -- get the next input character
+ ch = main_window:getch()
+ if not ch then
+
+ -- since there is no way to know the time with millisecond precision
+ -- we pause the the program until we get a key or the time limit
+ -- is reached
+ local t = 0
+ while true do
+ ch = main_window:getch()
+ if ch or t >= esc_delay then
+ break
+ end
+
+ -- wait some time, 50ms
+ curses.napms(50)
+ t = t + 50
+ end
+
+ -- nothing was typed... return Esc
+ if not ch then
+ return 27, "Esc", false
+ end
+ end
+ if ch > 96 and ch < 123 then
+ ch = ch - 32
+ end
+ end
+
+ -- map character to key
+ local key = key_map[ch]
+ local key_name = nil
+ if key then
+ key_name = alt and "Alt".. key or key
+ elseif (ch < 256) then
+ key_name = alt and "Alt".. string.char(ch) or string.char(ch)
+ else
+ return ch, '(noname)', alt
+ end
+
+ -- return key info
+ return ch, key_name, alt
+end
+
-- return module
return program