summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-12-28 00:24:54 +0800
committerruki <[email protected]>2017-12-27 20:29:28 +0800
commitba9ff696b98908ec469c463ccdb7a313bb56c04a (patch)
tree58d5cdebce6bb1ec5b1934887ef1171c87475294
parent5a9bc97b532309a1d13175e5ce4e82a2f430d58e (diff)
refresh cursor
-rw-r--r--xmake/core/ui/button.lua6
-rw-r--r--xmake/core/ui/curses.lua9
-rw-r--r--xmake/core/ui/program.lua53
-rw-r--r--xmake/core/ui/view.lua30
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()