summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-12-15 22:44:56 +0800
committerruki <[email protected]>2017-12-15 10:29:37 +0800
commitd81f894af27987981ef3fe39e013ad3f1fadfbcf (patch)
tree1678fafa209ee07cd1ab19375ffbc3b84c87cdee
parentb4c46182afdf442505f22bbf864ef2811933da49 (diff)
update screen in view
-rw-r--r--xmake/core/ui/application.lua3
-rw-r--r--xmake/core/ui/group.lua101
-rw-r--r--xmake/core/ui/view.lua48
3 files changed, 149 insertions, 3 deletions
diff --git a/xmake/core/ui/application.lua b/xmake/core/ui/application.lua
index c2b7069a6..2572e7e1d 100644
--- a/xmake/core/ui/application.lua
+++ b/xmake/core/ui/application.lua
@@ -53,6 +53,9 @@ function application:init(name)
-- init program
program.init(self, name)
+ -- save application
+ self:application_set(self)
+
-- add menubar, statusbar and desktop
self:insert(self:statusbar())
self:insert(self:menubar())
diff --git a/xmake/core/ui/group.lua b/xmake/core/ui/group.lua
index 86cf81bc4..80f0d991c 100644
--- a/xmake/core/ui/group.lua
+++ b/xmake/core/ui/group.lua
@@ -43,6 +43,9 @@ function group:init(name, bounds)
-- init view
view.init(self, name, bounds)
+ -- mark as selectable
+ self:option_set("selectable", true)
+
-- init child views
self._VIEWS = dlist()
end
@@ -79,6 +82,16 @@ function group:next(v)
return self._VIEWS:next(v)
end
+-- get the previous view
+function group:prev(v)
+ return self._VIEWS:prev(v)
+end
+
+-- get the current selected child view
+function group:current()
+ return self._CURRENT
+end
+
-- insert view
function group:insert(v)
@@ -111,9 +124,12 @@ function group:insert(v)
-- set it's parent view
v:parent_set(self)
- -- TODO select this view
+ -- set application
+ v:application_set(self:application())
+
+ -- select this view
if v:option("selectable") then
--- self:select(v)
+ self:select(v)
end
-- draw and show this view
@@ -139,12 +155,91 @@ function group:remove(v)
-- remove view
self._VIEWS:remove(v)
- -- TODO select next view
+ -- select next view
+ if self:current() == v then
+ self._CURRENT = nil
+ self:select_next()
+ end
-- unlock
self:unlock()
end
+-- select the child view
+function group:select(v)
+
+ -- check
+ assert(v == nil or (v:parent() == self and v:option("selectable")))
+
+ -- get the current selected view
+ local current = self:current()
+ if v == current then
+ return
+ end
+
+ -- undo the previous selected view
+ if current then
+
+ -- undo the current view first
+ if self:state("focused") then
+ current:state_set('focused', false)
+ end
+ current:state_set('selected', false)
+ end
+
+ -- update the current selected view
+ self._CURRENT = v
+
+ -- update the new selected view
+ if v then
+
+ -- modify view order and mark this view as top
+ if v:option("top_select") then
+ self._VIEWS:remove(v)
+ self._VIEWS:push(v)
+ end
+
+ -- select and focus this view
+ v:state_set('selected', true)
+ if self:state("focused") then
+ v:state_set('focused', true)
+ end
+ end
+end
+
+-- select the next view
+function group:select_next(forward, start)
+
+ -- is empty?
+ if self:empty() then
+ return
+ end
+
+ -- get current view
+ local current = start or self:current() or self:first()
+
+ -- forward?
+ if forward then
+ local next = self:next(current)
+ while next ~= current do
+ if next:option("selectable") and next:state("visible") then
+ self:select(next)
+ break
+ end
+ next = self:next(next)
+ end
+ else
+ local prev = self:prev(current)
+ while prev ~= current do
+ if prev:option("selectable") and prev:state("visible") then
+ self:select(prev)
+ break
+ end
+ prev = self:prev(prev)
+ end
+ end
+end
+
-- execute group
function group:execute()
end
diff --git a/xmake/core/ui/view.lua b/xmake/core/ui/view.lua
index cc2edce01..73539a854 100644
--- a/xmake/core/ui/view.lua
+++ b/xmake/core/ui/view.lua
@@ -28,6 +28,7 @@ $Id: view.lua 18 2007-06-21 20:43:52Z tngd $
--------------------------------------------------------------------------]]
-- load modules
+local log = require("ui/log")
local object = require("ui/object")
local canvas = require("ui/canvas")
local curses = require("ui/curses")
@@ -35,6 +36,9 @@ local curses = require("ui/curses")
-- define module
local view = view or object()
+-- the screen lock/update counter
+local screen_lock = 0
+
-- new view instance
function view:new(name, bounds)
@@ -148,6 +152,16 @@ function view:parent_set(parent)
self._PARENT = parent
end
+-- get the application
+function view:application()
+ return self._APPLICATION
+end
+
+-- set the application
+function view:application_set(app)
+ self._APPLICATION = app
+end
+
-- get the view window
function view:window()
return self._WINDOW
@@ -189,10 +203,16 @@ end
-- lock view
function view:lock()
+ screen_lock = screen_lock + 1
end
-- unlock view
function view:unlock()
+ assert(screen_lock > 0)
+ screen_lock = screen_lock - 1
+ if screen_lock == 0 then
+ self:_update_screen()
+ end
end
-- show view?
@@ -243,6 +263,34 @@ function view:option_set(name, enable)
self._OPTIONS[name] = enable
end
+-- update screen
+function view:_update_screen()
+
+ -- get application
+ local app = self:application()
+ assert(app, "cannot get application from view(" .. self:name() .. ")")
+
+ -- is visible?
+ if not app:state("visible") then
+ return
+ end
+
+ -- trace
+ log:print("view(%s): update screen ..", self:name())
+
+ -- get main window
+ local main_window = curses.main_window()
+
+ -- update screen
+ app:window():copy(main_window, 0, 0, 0, 0, app:height() - 1, app:width() - 1)
+
+ -- mark as refresh
+ main_window:noutrefresh()
+
+ -- do update
+ curses.doupdate()
+end
+
-- tostring(view)
function view:__tostring()
return string.format("<%s %s>", self:name(), tostring(self:bounds()))