aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2017-05-09 20:43:00 +0200
committerAlex Auvolat <alex@adnab.me>2017-05-09 20:43:00 +0200
commitb74a9f0c4b73bc3b98ec6c4345d9aaf4b6279f7a (patch)
treeedda3126acf99a0c9131c6ef293e8c69259a48b2
parent83cc53def0abb6f44ebd95a7175e717e3c66cd48 (diff)
downloadkogata-b74a9f0c4b73bc3b98ec6c4345d9aaf4b6279f7a.tar.gz
kogata-b74a9f0c4b73bc3b98ec6c4345d9aaf4b6279f7a.zip
Simili file manager
-rw-r--r--src/sysapp/login/main.lua113
-rw-r--r--src/syslua/lx/tk.lua115
2 files changed, 163 insertions, 65 deletions
diff --git a/src/sysapp/login/main.lua b/src/sysapp/login/main.lua
index 0303c4f..a246c87 100644
--- a/src/sysapp/login/main.lua
+++ b/src/sysapp/login/main.lua
@@ -25,7 +25,7 @@ local wm = tk.window_manager()
tk.init(gui, wm)
local img = tk.image(f)
-wm:add(img, "Window 1", 100, 16)
+wm:add({title = "Window 1", x = 100, y = 16}, img)
local img2 = tk.box({
center_content = true,
vscroll = true,
@@ -33,27 +33,118 @@ local img2 = tk.box({
vresize = true,
hresize = true,
}, tk.image(f))
-wm:add(img2, "Window 2", 16, 100)
+wm:add({title = "Window 2", x = 16, y = 100}, img2)
local img3 = tk.box({
constrain_size = true,
vresize = true,
hresize = true,
}, tk.image(f))
-wm:add(img3, "Window 3", 300, 150)
+wm:add({title = "Window 3", x = 300, y = 150}, img3)
local txt = tk.text({color = tk.rgb(0, 255, 0), width=200}, "Hello, world!\nThis is a long text")
-wm:add(txt, "Text example", 32, 32)
+wm:add({title = "Text example", x = 32, y = 32}, txt)
+
+
+function alert(text, on_dismiss)
+ local win = {}
+ win.widget =
+ tk.grid({},
+ { { tk.text({padding = 16}, text) },
+ { tk.box({center_content = true, height = 40},
+ tk.text({background = tk.rgb(0, 255, 0),
+ padding = 4,
+ on_click = function() win.close() end},
+ "Ok"))
+ } })
+ win.close = function()
+ sys.dbg_print("Hello!")
+ wm:remove(win.win)
+ if on_dismiss then on_dismiss() end
+ end
+ win.win = wm:add({title = "Alert",
+ x = math.random(0, gui.surface:width() - 100),
+ y = math.random(0, gui.surface:height() - 100),
+ }, win.widget)
+end
+
+function loopy()
+ alert("Hello, world !!", loopy)
+ gui.hide_cursor()
+ gui.surface:fillrect(0, 0, gui.surface:width(), gui.surface:height(), gui.surface:rgb(0, 0, 0))
+ gui.show_cursor()
+ wm:redraw(0, 0, gui.surface:width(), gui.surface:height())
+end
+loopy()
+
+-- A small file manager test :)
+
+local function open_listing(path)
+ local function fileline(name, path, size)
+ return {
+ tk.text(name),
+ tk.text(tostring(size)),
+ tk.box({center_content = true, width = 32},
+ tk.text({background = tk.rgb(128, 128, 255),
+ padding =2,
+ text_size = 12,
+ on_click = function() open_listing(path) end},
+ "open"))
+ }
+ end
+ local griditems = {
+ { tk.box({hresize = true, width = 200, constrain_size = true, min_width = 16, control_size = 8}, tk.text("Name")),
+ tk.box({hresize = true, width = 75, constrain_size = true, min_width = 16, control_size = 8}, tk.text("Size")),
+ tk.box({constrain_size = true}, tk.text("Actions"))
+ }
+ }
+ local fd = sys.open(path, sysdef.FM_READDIR)
+ if not fd then
+ alert("Could not FM_READDIR " .. path)
+ return
+ end
+
+ local i = 0
+ while true do
+ x = sys.readdir(fd, i)
+ if not x then break end
+ table.insert(griditems, fileline(x.name .. (x.type & sysdef.FT_DIR ~= 0 and "/" or ""),
+ path .. x.name .. "/",
+ x.size))
+ i = i + 1
+ end
+ sys.close(fd)
+
+ local grid = tk.grid({border_size = 1}, griditems)
+ wm:add({title = path,
+ x = math.random(0, gui.surface:width() - 100),
+ y = math.random(0, gui.surface:height() - 100)},
+ tk.box({vresize = true, hresize = true, vscroll = true, hscroll = true}, grid))
+end
+
+local function fsline(fs)
+ return {
+ tk.text(fs .. ":/"),
+ tk.box({center_content = true, width = 32},
+ tk.text({background = tk.rgb(128, 128, 255),
+ padding =2,
+ text_size = 12,
+ on_click = function() open_listing(fs .. ":/") end},
+ "open"))
+ }
+end
local grid = tk.grid({border_size = 1}, {
{ tk.box({hresize = true, width = 200, constrain_size = true, min_width = 16, control_size = 8}, tk.text("Name")),
- tk.box({hresize = true, width = 100, constrain_size = true, min_width = 16, control_size = 8}, tk.text("Size")) },
- { tk.text("File A"), tk.text("10k") },
- { tk.text("File B"), tk.text("20k") },
- { tk.text("File C"), tk.text("15k") },
+ tk.box({constrain_size = true}, tk.text("Actions"))
+ },
+ fsline("io"),
+ fsline("root"),
+ fsline("config"),
+ fsline("app"),
+ fsline("sys"),
})
-wm:add(tk.box({vresize = true, hresize = true, vscroll = true, hscroll = true}, grid),
- "Grid example", 300, 20)
-
+wm:add({title = "Filesystems", x = 300, y = 20},
+ tk.box({vresize = true, hresize = true, vscroll = true, hscroll = true}, grid))
mainloop.run()
diff --git a/src/syslua/lx/tk.lua b/src/syslua/lx/tk.lua
index 473ae3f..628ab91 100644
--- a/src/syslua/lx/tk.lua
+++ b/src/syslua/lx/tk.lua
@@ -135,6 +135,7 @@ function tk.widget(width, height, opts)
y = 0,
width = width,
height = height,
+ on_click = function(self) end,
}
if opts then
for k, v in pairs(opts) do
@@ -147,10 +148,18 @@ function tk.widget(width, height, opts)
-- does all the required redrawing
-- - redraw : redraws a portion of the widget
- -- can resize : checks if dimensiosn are valid
+ -- best resize : find best dimensions for resizing
-- widget can replace this if necessary
- function w:can_resize(width, height)
- return (not width or width > 0) and (not height or height > 0)
+ function w:best_resize(width, height)
+ width = width or self.width
+ width = math.max(self.min_width or 1, width)
+ if self.max_width then width = math.min(width, self.max_width) end
+
+ height = height or self.height
+ height = math.max(self.min_height or 1, height)
+ if self.max_height then height = math.min(height, self.max_height) end
+
+ return width, height
end
-- do resize : updates position and size values but does not redraw anything
@@ -216,9 +225,6 @@ function tk.widget(width, height, opts)
self.left_click_valid = false
end
- function w:on_click()
- end
-
function w:on_text_input(char)
-- Handler for text input
end
@@ -297,13 +303,12 @@ function tk.image(a, b)
local img = b or a
local opts = b and a or {}
+ opts.min_width = img:width()
+ opts.min_height = img:height()
+
local image = tk.widget(img:width(), img:height(), opts)
image.img = img
- function image:can_resize(width, height)
- return width >= self.img:width() and height >= self.img:height()
- end
-
function image:draw(x0, y0, buf)
local step = 20
local halfstep = 10
@@ -330,14 +335,20 @@ function tk.text(a, b)
-- Some defaults
opts.text_size = opts.text_size or 16
opts.padding = opts.padding or 2
- opts.background = opts.background or tk.rgb(255, 255, 255)
+ opts.background = opts.background or tk.rgb(220, 220, 220)
opts.color = opts.color or tk.rgb(0, 0, 0)
opts.line_spacing = opts.line_spacing or 1
if opts.word_wrap == nil then opts.word_wrap = true end
opts.font = opts.font or tk.fonts.default
opts.dy = opts.dy or -(opts.text_size//8)
- local txt = tk.widget(100, #string.split(text, "\n")*(opts.text_size + opts.line_spacing) - opts.line_spacing + 2*opts.padding, opts)
+ local lines = string.split(text, "\n")
+ local width = 0
+ for i = 1, #lines do
+ width = math.max(width, opts.font:text_width(lines[i], opts.text_size))
+ end
+
+ local txt = tk.widget(width+2*opts.padding, #lines*(opts.text_size + opts.line_spacing) - opts.line_spacing + 2*opts.padding, opts)
txt.text = text
function txt:draw(x0, y0, buf)
@@ -371,40 +382,29 @@ function tk.box(a, b)
opts.min_width = opts.min_width or 8
opts.min_height = opts.min_height or 8
opts.center_content = opts.center_content or false
- opts.constrain_size = opts.constrain_size or nil
- opts.background_color = opts.background_color or tk.rgb(190, 190, 190)
+ opts.constrain_size = opts.constrain_size or false
+ opts.background_color = opts.background_color or tk.rgb(220, 220, 220)
opts.control_size = opts.control_size or 12
local box = tk.widget(content.width, content.height, opts)
box.content = content
box.content.parent = box
- if box.center_content then
- if box.width > box.content.width then
- box.content.x = (box.width - box.content.width) // 2
- else
- box.content.x = 0
- end
- if box.height > box.content.height then
- box.content.y = (box.height - box.content.height) // 2
- else
- box.content.y = 0
- end
- else
- box.content.x = 0
- box.content.y = 0
- end
+ box.content.x = 0
+ box.content.y = 0
- function box:can_resize(width, height)
+ function box:best_resize(width, height)
if self.constrain_size then
- return self.content:can_resize(width, height)
+ return self.content:best_resize(width, height)
else
- if width then
- if self.min_width and width < self.min_width then return false end
- end
- if height then
- if self.min_height and height < self.min_height then return false end
- end
- return true
+ width = width or self.width
+ width = math.max(self.min_width or 1, width)
+ if self.max_width then width = math.min(width, self.max_width) end
+
+ height = height or self.height
+ height = math.max(self.min_height or 1, height)
+ if self.max_height then height = math.min(height, self.max_height) end
+
+ return width, height
end
end
@@ -435,10 +435,13 @@ function tk.box(a, b)
assert(c == self.content)
if self.constrain_size then
self:resize(w, h)
- elseif self.content:can_resize(w, h) then
- self.content:do_resize(w, h)
- self:do_resize(self.width, self.height)
- self:redraw(0, 0, self.width, self.height, self)
+ else
+ local w, h = self.content:best_resize(w, h)
+ if w ~= self.content.width or h ~= self.content.height then
+ self.content:do_resize(w, h)
+ self:do_resize(self.width, self.height)
+ self:redraw(0, 0, self.width, self.height, self)
+ end
end
end
@@ -569,8 +572,8 @@ function tk.grid(a, b)
local grid = tk.widget(nil, nil, opts)
grid.contents = contents
- function grid:can_resize(w, h)
- return w == self.col_pos[#self.contents[1]+1] and h == self.line_pos[#self.contents+1]
+ function grid:best_resize(w, h)
+ return self.col_pos[#self.contents[1]+1], self.line_pos[#self.contents+1]
end
function grid:reposition_elements()
@@ -605,8 +608,6 @@ function tk.grid(a, b)
self.contents[l][c]:do_resize(self.col_width[c], self.line_height[l])
end
end
- -- Resize me
- self:do_resize(self.col_pos[#self.contents[1]+1], self.line_pos[#self.contents+1])
end
function grid:get_lc(x, y)
@@ -644,7 +645,8 @@ function tk.grid(a, b)
end
function grid:resize_child(item, width, height)
- if not item:can_resize(width, height) then return end
+ local width, height = item:best_resize(width, height)
+ if width == item.width and height == item.height then return end
local l, c = item.grid_l, item.grid_c
local recalc = false
@@ -702,6 +704,7 @@ function tk.grid(a, b)
end
grid:reposition_elements()
+ grid.width, grid.height = grid:best_resize(0, 0)
return grid
end
@@ -719,12 +722,13 @@ function tk.window_manager()
wm.mouse_mb = false
wm.mouse_win = nil
- function wm:add(content, title, x, y)
- local win = tk.widget(content.width + 2, content.height + 22)
+ function wm:add(opts, content)
+ opts.x = opts.x or 24
+ opts.y = opts.y or 24
+ opts.title = opts.title or "--"
+
+ local win = tk.widget(content.width + 2, content.height + 22, opts)
win.parent = self
- win.x = x or 24
- win.y = y or 24
- win.title = title
win.visible = true
table.insert(self.windows, win)
self.window_pos[win] = {x = win.x, y = win.y, h = win.height, w = win.width}
@@ -737,7 +741,8 @@ function tk.window_manager()
function win:resize_child(c, w, h)
assert(c == self.content)
- if c:can_resize(w, h) then
+ local w, h = c:best_resize(w, h)
+ if w ~= c.width or h ~= c.height then
local reg1 = wm.window_pos[self]
c:do_resize(w, h)
@@ -758,7 +763,7 @@ function tk.window_manager()
self:draw_sub(x0, y0, buf, self.content)
buf:rect(-x0, -y0, self.width, self.height, buf:rgb(255, 128, 0))
- buf:fillrect(-x0+1, -y0+1, win.width-2, 20, buf:rgb(200, 200, 200))
+ buf:fillrect(-x0+1, -y0+1, win.width-2, 20, buf:rgb(255, 255, 255))
if win.title then
buf:write(-x0+2, -y0+2, win.title, tk.fonts.default, 16, buf:rgb(0, 0, 0))
end
@@ -797,6 +802,8 @@ function tk.window_manager()
end
self:redraw_win(win)
+
+ return win
end
function wm:remove(win)