diff options
| author | ruki <[email protected]> | 2017-12-28 00:24:54 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-12-27 20:29:28 +0800 |
| commit | ba9ff696b98908ec469c463ccdb7a313bb56c04a (patch) | |
| tree | 58d5cdebce6bb1ec5b1934887ef1171c87475294 | |
| parent | 5a9bc97b532309a1d13175e5ce4e82a2f430d58e (diff) | |
refresh cursor
| -rw-r--r-- | xmake/core/ui/button.lua | 6 | ||||
| -rw-r--r-- | xmake/core/ui/curses.lua | 9 | ||||
| -rw-r--r-- | xmake/core/ui/program.lua | 53 | ||||
| -rw-r--r-- | xmake/core/ui/view.lua | 30 |
4 files changed, 97 insertions, 1 deletions
diff --git a/xmake/core/ui/button.lua b/xmake/core/ui/button.lua index fe9a719c7..22413a83c 100644 --- a/xmake/core/ui/button.lua +++ b/xmake/core/ui/button.lua @@ -35,6 +35,12 @@ function button:init(name, bounds, text) -- init label label.init(self, name, bounds, text) + + -- mark as selectable + self:option_set("selectable", true) + + -- show cursor + self:cursor_show(true) end -- return module diff --git a/xmake/core/ui/curses.lua b/xmake/core/ui/curses.lua index 77cb004f6..5effd5f59 100644 --- a/xmake/core/ui/curses.lua +++ b/xmake/core/ui/curses.lua @@ -208,5 +208,14 @@ function curses.color_pair(fg, bg) return attr end +-- set cursor state +curses._cursor_set = curses._cursor_set or curses.cursor_set +function curses.cursor_set(state) + if curses._CURSOR_STATE ~= state then + curses._CURSOR_STATE = state + curses._cursor_set(state) + end +end + -- return module: curses return curses diff --git a/xmake/core/ui/program.lua b/xmake/core/ui/program.lua index 16518d357..014168ef3 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 log = require("ui/log") local rect = require("ui/rect") +local point = require("ui/point") local group = require("ui/group") local event = require("ui/event") local curses = require("ui/curses") @@ -222,6 +223,9 @@ function program:refresh() -- refresh main window self:window():copy(main_window, 0, 0, 0, 0, self:height() - 1, self:width() - 1) + -- refresh cursor + self:_refresh_cursor() + -- mark as refresh main_window:noutrefresh() @@ -360,5 +364,54 @@ function program:_input_key() return ch, key_name, alt end +-- refresh cursor +function program:_refresh_cursor() + + -- get the top focused view + local focused_view = self + while focused_view:type() == "group" and focused_view:current() do + focused_view = focused_view:current() + end + + -- get the cursor state of the top focused view + local cursor_state = 0 + if focused_view and focused_view:state("cursor_visible") then + cursor_state = focused_view:state("block_cursor") and 2 or 1 + end + + -- get the cursor position + local cursor = focused_view and focused_view:cursor() or point{0, 0} + if cursor_state ~= 0 then + local v = focused_view + while v:parent() do + + -- update the cursor position + cursor:addxy(v:bounds().sx, v:bounds().sy) + + -- is cursor visible? + if cursor.x < 0 or cursor.y < 0 or cursor.x >= v:parent():width() or cursor.y >= v:parent():height() then + cursor_state = 0 + break + end + + -- get the parent view + v = v:parent() + end + end + + -- update the cursor state + curses.cursor_set(cursor_state) + + -- get main window + local main_window = curses.main_window() + + -- move cursor position + if cursor_state ~= 0 then + main_window:move(cursor.y, cursor.x) + else + main_window:move(self:height() - 1, self:width() - 1) + end +end + -- return module return program diff --git a/xmake/core/ui/view.lua b/xmake/core/ui/view.lua index 593fdccb4..5b8449641 100644 --- a/xmake/core/ui/view.lua +++ b/xmake/core/ui/view.lua @@ -25,6 +25,7 @@ -- load modules local log = require("ui/log") local rect = require("ui/rect") +local point = require("ui/point") local object = require("ui/object") local canvas = require("ui/canvas") local curses = require("ui/curses") @@ -57,6 +58,8 @@ function view:init(name, bounds) -- init state local state = object() state.visible = true -- view visibility + state.cursor_visible = false -- cursor visibility + state.block_cursor = false -- block cursor state.selected = false -- current selected window inside group state.focused = false -- true if parent is also focused state.redraw = true -- need redraw @@ -78,7 +81,10 @@ function view:init(name, bounds) self._EVENTS = events -- init name - self._NAME = name + self._NAME = name + + -- init cursor + self._CURSOR = point {0, 0} -- init bounds and window self:bounds_set(bounds) @@ -307,6 +313,23 @@ function view:attr_set(name, value) self:invalidate() end +-- get cursor position +function view:cursor() + return self._CURSOR +end + +-- move cursor to the given position +function view:cursor_move(x, y) + self._CURSOR = point{ self:_limit(x, 0, self:width() - 1), self:_limit(y, 0, self:height() - 1) } +end + +-- show cursor? +function view:cursor_show(visible) + if self:state("cursor_visible") ~= visible then + self:state_set("cursor_visible", visible) + end +end + -- get background function view:background() local background = self:attr("background") @@ -321,6 +344,11 @@ function view:background_set(color) self:attr_set("background", color) end +-- limit value range +function view:_limit(value, minval, maxval) + return math.min(maxval, math.max(value, minval)) +end + -- need redraw view function view:_mark_redraw() |
