summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <Pixel@.(none)>2010-01-05 22:22:01 -0800
committerunknown <Pixel@.(none)>2010-01-05 22:22:01 -0800
commit628ed8138210d0f67cc35835f6fba96fcc7d932f (patch)
tree0357420e905b42533170ad2d71961373d82c7803
parent36624b05efae3fa82280a945fa2eb1dedc84e0b0 (diff)
parent69836d15333d9d48aecf3e0aef139c7eacf59214 (diff)
Merge branch 'master' of ssh+git://git.grumpycoder.net/pub/repo.git/Dalos
-rw-r--r--12-em-cross.tgabin0 -> 462 bytes
-rw-r--r--12-em-down.tgabin0 -> 356 bytes
-rw-r--r--12-em-plus.tgabin0 -> 342 bytes
-rw-r--r--12-em-up.tgabin0 -> 334 bytes
-rw-r--r--dalos-binaryops.lua114
-rw-r--r--dalos-buffer.lua30
-rw-r--r--dalos-cd.lua49
-rw-r--r--dalos-framebuffer.lua396
-rw-r--r--dalos-hexview.lua197
-rw-r--r--dalos-input.lua44
-rw-r--r--dalos-limiter.lua60
-rw-r--r--dalos-luafilter.lua174
-rw-r--r--dalos-luahandle.lua52
-rw-r--r--dalos-struct.lua601
-rw-r--r--dalos-tee.lua50
-rw-r--r--dalos-textbuffer.lua35
-rw-r--r--dalos-textview.lua53
-rw-r--r--dalos.lua797
-rw-r--r--iupe-dbuffer.lua4
-rw-r--r--iupe-hexview.lua57
20 files changed, 2490 insertions, 223 deletions
diff --git a/12-em-cross.tga b/12-em-cross.tga
new file mode 100644
index 0000000..06f0531
--- /dev/null
+++ b/12-em-cross.tga
Binary files differ
diff --git a/12-em-down.tga b/12-em-down.tga
new file mode 100644
index 0000000..3416152
--- /dev/null
+++ b/12-em-down.tga
Binary files differ
diff --git a/12-em-plus.tga b/12-em-plus.tga
new file mode 100644
index 0000000..337e3c5
--- /dev/null
+++ b/12-em-plus.tga
Binary files differ
diff --git a/12-em-up.tga b/12-em-up.tga
new file mode 100644
index 0000000..2ca9149
--- /dev/null
+++ b/12-em-up.tga
Binary files differ
diff --git a/dalos-binaryops.lua b/dalos-binaryops.lua
new file mode 100644
index 0000000..e4c6ed9
--- /dev/null
+++ b/dalos-binaryops.lua
@@ -0,0 +1,114 @@
+dalosp.binaryops = {
+ operations = {
+ XOR = 0,
+ AND = 1,
+ OR = 2,
+ ADD = 3,
+ SUB = 4,
+ },
+
+ opnames = {
+ [0] = "XOR",
+ [1] = "AND",
+ [2] = "OR",
+ [3] = "ADD",
+ [4] = "SUB",
+ },
+
+ configure = function (self)
+ local accept, operation, maximize = iup.GetParam(self.name .. " configuration", nil, [[
+Operation: %l|xor|and|or|add|sub|{Binary operation that's going to occur}
+Maximize: %b[No,Yes]{Check if you want to maximize the output}
+]], self.op or 0, self.maximize and 1 or 0)
+ if accept then
+ self.extra.op = operation
+ self.extra.maximize = maximize == 1
+ self:input_change()
+ end
+ end,
+
+ get_settings = function (self)
+ return { op = self.extra.op, maximize = self.extra.maximize }
+ end,
+
+ input_change = function (self, ind)
+ local h1 = self:get_linked_input(1)
+ local h2 = self:get_linked_input(2)
+ local op = self.extra.op or dalosp.binaryops.operations.XOR
+ if h1 and h2 then
+ self.color = cd.GREEN
+ local obj = {
+ h1 = h1,
+ h2 = h2,
+ op = op,
+ maximize = self.extra.maximize,
+ offset = 0,
+ size = self.extra.maximize and math.max(h1:getsize(), h2:getsize()) or math.min(h1:getsize(), h2:getsize()),
+ getname = function () return self.name end,
+ do_read = function (self, count)
+ self.h1:seek(self.offset)
+ self.h2:seek(self.offset)
+
+ local t1, r1 = self.h1:read(count)
+ local t2, r2 = self.h2:read(count)
+ local r = self.maximize and math.max(r1, r2) or math.min(r1, r2)
+ self.offset = self.offset + r
+ if r == 0 then self.got_eof = true return 0 end
+ local t = {}
+ local op
+ if self.op == dalosp.binaryops.operations.XOR then
+ op = bit.bxor
+ elseif self.op == dalosp.binaryops.operations.AND then
+ op = bit.band
+ elseif self.op == dalosp.binaryops.operations.OR then
+ op = bit.bor
+ elseif self.op == dalosp.binaryops.operations.ADD then
+ op = function(a, b) return a + b end
+ elseif self.op == dalosp.binaryops.operations.SUB then
+ op = function(a, b) return a - b end
+ end
+ for i = 0, r - 1 do
+ t[i] = bit.band(op(t1[i % r1], t2[i % r2]), 255)
+ end
+ return r, t
+ end,
+ }
+ self:set_houtput(dalos.luahandle(obj))
+ self.dcanvas:draw()
+ else
+ self.color = cd.YELLOW
+ self:set_houtput(nil)
+ self.dcanvas:draw()
+ end
+ end,
+
+ draw = function (self, cv, x, y, w, h)
+ dalosp.object.default_draw(self, cv, x, y, w, h)
+ local cx, cy = x + w / 2, cv:InvertYAxis(y + h / 2)
+ local op = self.extra.op or dalosp.binaryops.operations.XOR
+ cv:TextAlignment(cd.CENTER)
+ cv:Foreground(cd.BLACK)
+ cv:Text(cx, cy, dalosp.binaryops.opnames[op])
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 2
+ tab.noutputs = 1
+ tab.otype = dalos.objtype.LUA_FILTER
+ tab.configure = dalosp.binaryops.configure
+ tab.input_change = dalosp.binaryops.input_change
+ tab.default_name = "Binary Ops"
+ tab.draw = dalosp.binaryops.draw
+ tab.get_settings = dalosp.binaryops.get_settings
+ tab.ntype = "Binary Ops"
+ local extra = { }
+ if settings then extra.op = settings.op extra.maximize = settings.maximize end
+
+ local obj = dalos.object(d, tab, extra)
+
+ return obj
+ end,
+}
+
+dalos.binaryops = dalosp.binaryops.create
+dalos:register_obj("Binary Ops", dalos.binaryops, "Basic Filters")
diff --git a/dalos-buffer.lua b/dalos-buffer.lua
new file mode 100644
index 0000000..3743f46
--- /dev/null
+++ b/dalos-buffer.lua
@@ -0,0 +1,30 @@
+dalosp.buffer = {
+ input_change = function (self, ind)
+ local h = self:get_linked_input(1)
+ if h then
+ self.color = cd.GREEN
+ local b = Buffer(true)
+ b:copyfrom(self:get_linked_input(1))
+ self:set_houtput(b)
+ else
+ self:set_houtput(nil)
+ self.color = cd.YELLOW
+ end
+ self.dcanvas:draw()
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 1
+ tab.noutputs = 1
+ tab.otype = dalos.objtype.LUA_FILTER
+ tab.default_name = "Buffer"
+ tab.input_change = dalosp.buffer.input_change
+ tab.ntype = "Buffer"
+ local obj = dalos.object(d, tab, extra)
+
+ return obj
+ end,
+}
+
+dalos.buffer = dalosp.buffer.create
+dalos:register_obj("Buffer", dalos.buffer, "Basic Filters")
diff --git a/dalos-cd.lua b/dalos-cd.lua
new file mode 100644
index 0000000..cb0b6a7
--- /dev/null
+++ b/dalos-cd.lua
@@ -0,0 +1,49 @@
+loadmodule "luacd"
+
+dalosp.cd = {
+ get_settings = function (self)
+ return { filename = self.extra.filename }
+ end,
+
+ configure = function (self)
+ local drives_list = self.extra.drives_list
+ local list = ""
+ for i, v in ipairs(drives_list) do
+ list = list .. v .. "|"
+ end
+ local s, id = iup.GetParam("CD drive", nil, "CD drive: %l|" .. list .. "\n", 0)
+
+ if s then
+ self.extra.filename = "cd:" .. drives_list[id + 1]
+ local s, v = pcall(cdabstract, self.extra.filename)
+ if s then
+ self:set_houtput(v)
+ return
+ end
+ end
+ self:set_houtput(nil)
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 0
+ tab.noutputs = 1
+ tab.otype = dalos.objtype.HANDLE
+ tab.configure = dalosp.cd.configure
+ tab.default_name = "CD"
+ tab.ntype = "CD"
+ tab.get_settings = dalosp.cd.get_settings
+ local extra = { drives_list = cdprobe() }
+ if settings then extra.filename = settings.filename end
+ local obj = dalos.object(d, tab, extra)
+
+ if extra.filename then
+ local s, v = pcall(cdabstract, extra.filename)
+ if s then obj:set_houtput(v) end
+ end
+
+ return obj
+ end,
+}
+
+dalos.cd = dalosp.cd.create
+dalos:register_obj("CD", dalos.cd, "Basic Inputs")
diff --git a/dalos-framebuffer.lua b/dalos-framebuffer.lua
new file mode 100644
index 0000000..27e183c
--- /dev/null
+++ b/dalos-framebuffer.lua
@@ -0,0 +1,396 @@
+load "iupe-dbuffer.lua"
+
+dalosp.framebuffer = {
+ get_settings = function (self)
+ local extra = self.extra
+ return {
+ width = extra.width,
+ height = extra.height,
+ bpp = extra.bpp,
+ zoom = extra.zoom,
+ ppdir = extra.ppdir,
+ flipx = extra.flipx,
+ flipy = extra.flipy,
+ }
+ end,
+
+ input_change = function (self, ind)
+ local h = self:get_linked_input(ind)
+ if ind == 2 then
+ if h then
+ local cfg, s = h:readfile()
+ s, cfg = pcall(loadstring, "local cfg = " .. cfg .. "\nreturn cfg\n")
+ if s then
+ self:apply_config(cfg)
+ self.extra.fb:prepare()
+ self.extra.fb:draw()
+ end
+ end
+ return
+ end
+
+ if h then h.getnextbyte = dalosp.framebuffer.getnextbyte end
+ self:apply_config{}
+ self.extra.fb:prepare()
+ self.extra.fb:draw()
+ end,
+
+ activate = function (self)
+ self.extra.dlg:show()
+ end,
+
+ configure = function (self)
+ local extra = self.extra
+ invert_lookup = {
+ [1] = 0,
+ [2] = 1,
+ [4] = 2,
+ [8] = 3,
+ [24] = 4,
+ [32] = 5,
+ }
+ lookup = {
+ [0] = 1,
+ [1] = 2,
+ [2] = 4,
+ [3] = 8,
+ [4] = 24,
+ [5] = 32,
+ }
+ local owidth, oheight, obpp, oppdir, oflipx, oflipy = extra.width, extra.height, extra.bpp, extra.ppdir, not not extra.flipx, not not extra.flipy
+ local cb = function (dlg, pi)
+ if pi < 0 then return end
+ local width, height, bpp, dir
+ width = iup.GetParamParam(dlg, 1).value + 0
+ height = iup.GetParamParam(dlg, 2).value + 0
+ bpp = iup.GetParamParam(dlg, 3).value + 0
+ dir = iup.GetParamParam(dlg, 4).value + 0
+ flipx = (iup.GetParamParam(dlg, 5).value + 0) ~= 0
+ flipy = (iup.GetParamParam(dlg, 6).value + 0) ~= 0
+ self:apply_config{ width = width, height = height, bpp = lookup[bpp], dir = dir, flipx = flipx, flipy = flipy }
+ self.extra.fb:prepare()
+ self.extra.fb:draw()
+ end
+ local s, nname = iup.GetParam(self.name .. " configuration", cb, [[
+New name: %s
+Width: %i
+Height: %i
+Bpp: %l|1 bpp|2 bpp|4 bpp|8 bpp|24 bpp|32 bpp|
+Packed Pixels: %l|Little Endian|Big Endian|
+Flip X axis: %b
+Flip Y axis: %b
+]], self.name, owidth, oheight, invert_lookup[obpp], oppdir, oflipx and 1 or 0, oflipy and 1 or 0)
+ if not s then
+ self:apply_config{ width = owidth, height = oheight, bpp = obpp, ppdir = oppdir, flipx = oflipx, flipy = oflipy }
+ self.extra.fb:prepare()
+ self.extra.fb:draw()
+ else
+ self.name = nname
+ end
+ end,
+
+ apply_config = function (self, cfg)
+ local extra = self.extra
+ local fb = extra.fb
+ local h = self:get_linked_input(1)
+ if cfg.width then extra.width = cfg.width end
+ if cfg.height then extra.height = cfg.height end
+ if cfg.bpp then extra.bpp = cfg.bpp end
+ if cfg.ppdir then extra.ppdir = cfg.ppdir end
+ if cfg.flipx then extra.flipx = cfg.flipx end
+ if cfg.flipy then extra.flipy = cfg.flipy end
+ if cfg.zoom then extra.zoom = cfg.zoom end
+ local zoom = 2 ^ extra.zoom
+ local posx = fb.posx
+ local posy = fb.posy
+ local dx = fb.dx + 0
+ local dy = fb.dy + 0
+ local fw = math.floor(extra.width * zoom)
+ local fh = math.floor(extra.height * zoom)
+ if dx >= (fb.xmax - fb.xmin) then posx = math.floor((fw - dx) / 2) end
+ if dy >= (fb.ymax - fb.ymin) then posy = math.floor((fh - dy) / 2) end
+ fb.xmax = fw
+ fb.ymax = fh
+ cfg = {
+ h = h,
+ width = extra.width,
+ height = extra.height,
+ bpp = extra.bpp,
+ ppdir = extra.ppdir,
+ flipx = extra.flipx,
+ flipy = extra.flipy,
+ zoom = zoom,
+ x = -posx,
+ y = -posy,
+ fw = fw,
+ fh = fh,
+ }
+ fb.cfg = cfg
+ local cvwidth, cvheight = fb.width or 0, fb.height or 0
+ cvwidth, cvheight = cvwidth + 0, cvheight + 0
+ end,
+
+ getnextbyte = function (h)
+ return h:tell() ~= h:getsize() and h:readU8() or 0
+ end,
+
+ getbit = function (cfg)
+ local rc
+ local h = cfg.h
+ local stateful = cfg.stateful
+ if cfg.bpp >= 8 then return end
+ stateful = cfg.stateful
+ if not stateful or bit.band(stateful, 0x7f) == 0 then
+ stateful = h:getnextbyte() * 2 + 1
+ else
+ stateful = stateful * 2
+ end
+ cfg.stateful = stateful
+ return bit.band(bit.rshift(stateful, 8), 1)
+ end,
+
+ getnextpixel = function (cfg)
+ local rc
+ local r, g, b
+ local h = cfg.h
+ local getbit = function() return dalosp.framebuffer.getbit(cfg) end
+ if cfg.bpp == 1 then
+ rc = getbit() * 255
+ r, g, b = rc, rc, rc
+ elseif cfg.bpp == 2 then
+ rc = getbit() * 2
+ rc = (rc + getbit()) * 255 / 3
+ r, g, b = rc, rc, rc
+ elseif cfg.bpp == 4 then
+ rc = getbit() * 8
+ rc = rc + getbit() * 4
+ rc = rc + getbit() * 2
+ rc = (rc + getbit()) * 255 / 15
+ r, g, b = rc, rc, rc
+ elseif cfg.bpp == 8 then
+ rc = h:getnextbyte()
+ r, g, b = rc, rc, rc
+ elseif cfg.bpp == 24 then
+ r = h:getnextbyte()
+ g = h:getnextbyte()
+ b = h:getnextbyte()
+ elseif cfg.bpp == 32 then
+ r = h:getnextbyte()
+ g = h:getnextbyte()
+ b = h:getnextbyte()
+ h:getnextbyte()
+ end
+ return r, g, b
+ end,
+
+ prepare = function (self)
+ local cfg = self.cfg
+ local h = cfg.h
+ local width = cfg.width
+ local height = cfg.height
+ local bpp = cfg.bpp
+ local ppdir = cfg.ppdir
+ local flipx = cfg.flipx
+ local flipy = not cfg.flipy
+ local cim = im.ImageCreate(width, height, im.RGB, im.BYTE)
+ self.cim = cim
+ cim:Clear()
+ if not h then return iup.DEFAULT end
+ local getnextpixel = self.getnextpixel
+
+ h:seek(0)
+ cfg.stateful = 0
+ local r, g, b = cim[0], cim[1], cim[2]
+
+ for y = 0, height - 1 do
+ for x = 0, width - 1 do
+ local px, py = flipx and width - x - 1 or x, flipy and height - y - 1 or y
+ r[py][px], g[py][px], b[py][px] = getnextpixel(cfg)
+ end
+ end
+
+ return iup.DEFAULT
+ end,
+
+ draw = function (self)
+ local cvdb = self.cvdb
+ if not cvdb then return iup.DEFAULT end
+ cvdb:Clear()
+ local cim = self.cim
+ local cfg = self.cfg
+ cim:cdCanvasPutImageRect(cvdb, cfg.x, cvdb:InvertYAxis(cfg.y + cfg.fh), cfg.fw, cfg.fh, 0, 0, 0, 0)
+ cvdb:Flush()
+ end,
+
+ resize_cb = function (self, width, height)
+ self.dx = width
+ self.dy = height
+ self.posx = self.posx
+ self.posy = self.posy
+ iupep.dbuffer.resize_cb(self, width, height)
+ self.obj:apply_config{}
+ self:draw()
+ end,
+
+ fimg2canvas = function (self, ix, iy)
+ local cfg = self.cfg
+ local cx, cy
+ return ix + cfg.x, iy + cfg.y
+ end,
+
+ canvas2fimg = function (self, cx, cy)
+ local cfg = self.cfg
+ return cx - cfg.x, cy - cfg.y
+ end,
+
+ img2canvas = function (self, ix, iy)
+ local cfg = self.cfg
+ return math.floor(ix * cfg.zoom + cfg.x), math.floor(iy * cfg.zoom + cfg.y)
+ end,
+
+ canvas2img = function (self, cx, cy)
+ local cfg = self.cfg
+ return math.floor((cx - cfg.x) / cfg.zoom), math.floor((cy - cfg.y) / cfg.zoom)
+ end,
+
+ scroll_cb = function (self, op, posx, posy)
+ self:resize_cb(self.width, self.height)
+ end,
+
+ wheel_cb = function (self, delta, x, y, status)
+ local ox, oy = self:canvas2img(x, y)
+ local opx, opy = self.cfg.x, self.cfg.y
+ self.obj:apply_config { zoom = self.obj.extra.zoom + (delta / 10) }
+ local nx, ny = self:img2canvas(ox, oy)
+ local dx, dy = ox - nx, oy - ny
+ self.posx, self.posy = -opx - dx, -opy - dy
+ self:resize_cb(self.width, self.height)
+ end,
+
+ motion_cb = function (self, x, y)
+ local ox, oy = self:canvas2img(x, y)
+ local nx, ny = self:img2canvas(ox, oy)
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 2
+ tab.noutputs = 0
+ tab.otype = dalos.objtype.LUA_VIEWER
+ tab.activate = dalosp.framebuffer.activate
+ tab.configure = dalosp.framebuffer.configure
+ tab.input_change = dalosp.framebuffer.input_change
+ tab.default_name = "Framebuffer"
+ tab.ntype = "Framebuffer"
+ tab.get_settings = dalosp.framebuffer.get_settings
+ local extra = {
+ width = settings.width or 256,
+ height = settings.height or 256,
+ bpp = settings.bpp or 32,
+ ppdir = settings.dir or 0,
+ flipx = settings.flipx,
+ flipy = settings.flipy,
+ zoom = settings.zoom or 0,
+ }
+
+ local obj = dalos.object(d, tab, extra)
+
+ obj.apply_config = dalosp.framebuffer.apply_config
+
+ local fb = iup.canvas {
+ expand = "Yes",
+ font = "Courier, 8",
+ action = iupep.dbuffer.action,
+ map_cb = iupep.dbuffer.map_cb,
+ unmap_cb = iupep.dbuffer.unmap_cb,
+ resize_cb = dalosp.framebuffer.resize_cb,
+ motion_cb = dalosp.framebuffer.motion_cb,
+ draw = dalosp.framebuffer.draw,
+ scroll_cb = dalosp.framebuffer.scroll_cb,
+ wheel_cb = dalosp.framebuffer.wheel_cb,
+ prepare = dalosp.framebuffer.prepare,
+ img2canvas = dalosp.framebuffer.img2canvas,
+ canvas2img = dalosp.framebuffer.canvas2img,
+ fimg2canvas = dalosp.framebuffer.img2canvas,
+ canvas2fimg = dalosp.framebuffer.canvas2img,
+ getnextpixel = dalosp.framebuffer.getnextpixel,
+ rastersize = extra.width .. "x" .. extra.height,
+ scrollbar = "Yes",
+ dx = 1,
+ dy = 1,
+ linex = 1,
+ liney = 1,
+ xmax = 0,
+ ymax = 0,
+ xautohide = "No",
+ yautohide = "No",
+ obj = obj,
+ }
+ local dlg = iup.dialog {
+ iup.vbox {
+ fb,
+ iup.hbox {
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -4 } fb:resize_cb(fb.width, fb.height) end,
+ title = "1:16",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -3 } fb:resize_cb(fb.width, fb.height) end,
+ title = "1:8",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -2 } fb:resize_cb(fb.width, fb.height) end,
+ title = "1:4",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = -1 } fb:resize_cb(fb.width, fb.height) end,
+ title = "1:2",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 0 } fb:resize_cb(fb.width, fb.height) end,
+ title = "1:1",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 1 } fb:resize_cb(fb.width, fb.height) end,
+ title = "2:1",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 2 } fb:resize_cb(fb.width, fb.height) end,
+ title = "4:1",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 3 } fb:resize_cb(fb.width, fb.height) end,
+ title = "8:1",
+ },
+ iup.fill{},
+ iup.button {
+ action = function () fb.posx, fb.posy = 0, 0 obj:apply_config { zoom = 4 } fb:resize_cb(fb.width, fb.height) end,
+ title = "16:1",
+ },
+ iup.fill{},
+ },
+ },
+ size = "320x200",
+ title = obj.name,
+ shrink = "Yes",
+ }
+ extra.dlg = dlg
+ extra.fb = fb
+
+ obj:apply_config{}
+ fb:prepare()
+ fb:draw()
+
+ return obj
+ end,
+}
+
+dalos.framebuffer = dalosp.framebuffer.create
+dalos:register_obj("Framebuffer", dalos.framebuffer, "Basic Viewers")
diff --git a/dalos-hexview.lua b/dalos-hexview.lua
new file mode 100644
index 0000000..b59993a
--- /dev/null
+++ b/dalos-hexview.lua
@@ -0,0 +1,197 @@
+load "iupe-hexview.lua"
+load "iupe-hexview-toolbox.lua"
+
+dalosp.hexview = {
+ activate = function (self)
+ self.extra.hvdlg:show()
+ end,
+
+ input_change = function (self, ind)
+ local extra = self.extra
+ local hv = extra.hv
+ local h = self:get_linked_input(ind)
+ if not h then
+ self.color = cd.YELLOW
+ hv:updatehandle(nil)
+ self.dcanvas:draw()
+ return
+ end
+ if not h:canread() or not h:canseek() then
+ self.color = cd.RED
+ hv:updatehandle(nil)
+ self.dcanvas:draw()
+ return
+ end
+ self.color = cd.GREEN
+ for i = 1, 12 do
+ self:set_houtput(nil, i)
+ self.oldcursors[i] = -1
+ end
+ hv:updatehandle(h)
+ self.dcanvas:draw()
+ end,
+
+ configure = function (self)
+ local s, newname, gsx, gsy, dgsx, dgsy, dl, ml =
+ iup.GetParam(self.name .. " properties", nil, [[
+Name: %s
+Gridsize X: %i
+Gridsize Y: %i
+Default gridsize X: %i
+Default gridsize Y: %i
+Lines: %i
+Marker lengths: %b
+]],
+ self.name, self.extra.hv.gridsize.x, self.extra.hv.gridsize.y, iupep.hexview.gridsize.x, iupep.hexview.gridsize.y,
+ self.extra.hv.displaylines, self.extra.hv.showmarkerslengths and 1 or 0)
+ if not s then return end
+ self.name = newname
+ self.extra.hv.gridsize.x = gsx
+ self.extra.hv.gridsize.y = gsy
+ iupep.hexview.gridsize.x = dgsx
+ iupep.hexview.gridsize.y = dgsy
+ self.extra.hv.displaylines = dl
+ self.extra.hv.showmarkerslengths = ml == 1
+ end,
+
+ get_settings = function (self)
+ local hv = self.extra.hv
+ local r = {
+ mcursor = hv.mcursor + 0,
+ kcursor = hv.kcursor + 0,
+ markers = {},
+ filecursor = hv.filecursor + 0,
+ displaylines = hv.displaylines + 0,
+ gridsize = hv.gridsize,
+ showmarkerslengths = hv.showmarkerslengths,
+ }
+ for i = 1, 10 do
+ r.markers[i] = hv.markers[i] + 0
+ end
+ return r
+ end,
+
+ output_change = function (self, ind)
+ self.extra.hv.markerslengths[ind] = 0
+ self.watchees[ind] = self.outputs[ind] and true or false
+ self:set_houtput(nil, ind)
+ self.oldcursors[ind] = -1
+ self:dalos_hv_cb(self.extra.hv)
+ end,
+
+ update_houtput = function (self, ind, cursor)
+ local hv = self.extra.hv
+ local h = self:get_linked_input(1)
+ local maxsize = h and h:getsize() or -1
+ cursor = cursor + 0
+ if cursor >= 0 and h and self.watchees[ind] then
+ if cursor >= maxsize then
+ self:set_houtput(nil, ind)
+ return
+ end
+ h:seek(cursor)
+ local obj = {
+ h = h,
+ hvo = self,
+ ind = ind,
+ origin = cursor,
+ size = maxsize - cursor,
+ getname = function (self) return self.hvo.name .. ":" .. self.ind end,
+ getmodif = function (self) return self.h:getmodif() end,
+ do_seek = function (self)
+ self.h:seek(self.offset + self.origin)
+ self:post_read()
+ end,
+ do_read = function (self, count, userdata)
+ return self.h:read(count, userdata)
+ end,
+ post_read = function (self, count)
+ local ol = hv.markerslengths[ind]
+ local nl = self.offset
+ if nl > ol then
+ hv.markerslengths[ind] = nl
+ if hv.showmarkerslengths then
+ hv:draw()
+ end
+ end
+ end,
+ }
+ self:set_houtput(dalos.luahandle(obj), ind)
+ end
+ end,
+
+ dalos_hv_cb = function (self, hv, reset)
+ local m
+ for i = 1, 10 do
+ m = hv.markers[i]
+ if m and self.oldcursors[i] ~= m then
+ self:update_houtput(i, m)
+ self.oldcursors[i] = m
+ end
+ end
+
+ m = hv.kcursor
+ if m and self.oldcursors[11] ~= m then
+ self:update_houtput(11, m)
+ self.oldcursors[11] = m
+ end
+
+ m = hv.mcursor
+ if m and self.oldcursors[12] ~= m then
+ self:update_houtput(12, m)
+ self.oldcursors[12] = m
+ end
+ end,
+
+ create = function (d, tab, settings)
+ tab.otype = dalos.objtype.LUA_FILTER
+ tab.activate = dalosp.hexview.activate
+ tab.input_change = dalosp.hexview.input_change
+ tab.output_change = dalosp.hexview.output_change
+ tab.configure = dalosp.hexview.configure
+ tab.get_settings = dalosp.hexview.get_settings
+ tab.ninputs = 1
+ tab.noutputs = 12
+ tab.default_name = "Hexview"
+ tab.ntype = "Hexview"
+
+ local extra = { }
+
+ local obj = dalos.object(d, tab, extra)
+
+ local hv = iupe.hexview { }
+ local hvtb = iupe.hexview_toolbox { hexview = hv }
+ local hvdlg = iup.dialog { iup.hbox { iup.frame { hv }, iup.sbox { direction = "WEST", hvtb } }, title = obj.name, size = "500x", shrink = "Yes" }
+
+ extra.hv = hv
+ extra.hvtb = hvtb
+ extra.hvdlg = hvdlg
+
+ obj.oldcursors = { }
+ obj.watchees = { }
+ obj.update_houtput = dalosp.hexview.update_houtput
+ for i = 1, 12 do obj.oldcursors[i] = -1 end
+
+ if settings then
+ if settings.markers then
+ for i = 1, 10 do
+ if settings.markers[i] then hv.markers[i] = settings.markers[i] end
+ end
+ end
+ if settings.mcursor then hv.mcursor = settings.mcursor end
+ if settings.kcursor then hv.kcursor = settings.kcursor end
+ if settings.filecursor then hv.filecursor = settings.filecursor end
+ if settings.displaylines then hv.displaylines = settings.displaylines end
+ if settings.gridsize then hv.gridsize.x, hv.gridsize.y = settings.gridsize.x, settings.gridsize.y end
+ if settings.showmarkerslengths then hv.showmarkerslengths = settings.showmarkerslengths end
+ end
+
+ hv:registercb(dalosp.hexview.dalos_hv_cb, obj)
+ obj.dalos_hv_cb = dalosp.hexview.dalos_hv_cb
+
+ return obj
+ end,
+}
+
+dalos.hexview = dalosp.hexview.create
+dalos:register_obj("Hexview", dalos.hexview, "Basic Viewers")
diff --git a/dalos-input.lua b/dalos-input.lua
new file mode 100644
index 0000000..bf37b9d
--- /dev/null
+++ b/dalos-input.lua
@@ -0,0 +1,44 @@
+dalosp.input = {
+ get_settings = function (self)
+ return { filename = self.extra.filename }
+ end,
+
+ configure = function (self)
+ local dlg = iup.filedlg {
+ dialogtype = "Open",
+ file = self.extra.filename,
+ }
+ iup.Popup(dlg)
+ if dlg.status ~= -1 then
+ local s, v = pcall(Input, dlg.value)
+ if s then
+ self:set_houtput(v)
+ return
+ end
+ end
+ self:set_houtput(nil)
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 0
+ tab.noutputs = 1
+ tab.otype = dalos.objtype.HANDLE
+ tab.configure = dalosp.input.configure
+ tab.default_name = "Input"
+ tab.ntype = "Input"
+ tab.get_settings = dalosp.input.get_settings
+ local extra = { }
+ if settings then extra.filename = settings.filename end
+ local obj = dalos.object(d, tab, extra)
+
+ if extra.filename then
+ local s, v = pcall(Input, extra.filename)
+ if s then obj:set_houtput(v) end
+ end
+
+ return obj
+ end,
+}
+
+dalos.input = dalosp.input.create
+dalos:register_obj("Input", dalos.input, "Basic Inputs")
diff --git a/dalos-limiter.lua b/dalos-limiter.lua
new file mode 100644
index 0000000..5643f30
--- /dev/null
+++ b/dalos-limiter.lua
@@ -0,0 +1,60 @@
+dalosp.limiter = {
+ configure = function (self)
+ local accept, limit = iup.GetParam(self.name .. " configuration", nil, [[
+Limit: %i{The actual size this limiter is going to produce}
+]], self.op or 0, self.maximize and 1 or 0)
+ if accept then
+ self.extra.limit = limit
+ self:input_change()
+ end
+ end,
+
+ get_settings = function (self)
+ return { limit = self.extra.limit }
+ end,
+
+ input_change = function (self, ind)
+ local h = self:get_linked_input(1)
+ if h then
+ self.color = cd.GREEN
+ local obj = {
+ h = h,
+ size = math.min(h:getsize(), self.extra.limit),
+ getname = function () return self.name end,
+ do_read = function (self, count, userdata)
+ return self.h:read(count, userdata)
+ end,
+ do_seek = function (self)
+ self.h:seek(self.offset, SEEK_SET)
+ end,
+ }
+ self:set_houtput(dalos.luahandle(obj))
+ self.dcanvas:draw()
+ else
+ self.color = cd.YELLOW
+ self:set_houtput(nil)
+ self.dcanvas:draw()
+ end
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 1
+ tab.noutputs = 1
+ tab.otype = dalos.objtype.LUA_FILTER
+ tab.configure = dalosp.limiter.configure
+ tab.input_change = dalosp.limiter.input_change
+ tab.default_name = "Limiter"
+ tab.ntype = "Limiter"
+ tab.get_settings = dalosp.limiter.get_settings
+ local extra = { }
+ if not settings then settings = {} end
+ extra.limit = settings.limit or 0
+
+ local obj = dalos.object(d, tab, extra)
+
+ return obj
+ end,
+}
+
+dalos.limiter = dalosp.limiter.create
+dalos:register_obj("Limiter", dalos.limiter, "Basic Filters")
diff --git a/dalos-luafilter.lua b/dalos-luafilter.lua
new file mode 100644
index 0000000..312aff7
--- /dev/null
+++ b/dalos-luafilter.lua
@@ -0,0 +1,174 @@
+dalosp.luafilter = {
+ templates = {},
+
+ default_code = [[
+-- available globals:
+
+-- ninputs, noutputs: numbers
+
+-- get_input(ind): handle
+-- del_output(ind): nil
+-- new_output(ind): nil
+-- set_color(c) : nil
+
+function activate()
+end
+
+function read(ind, count, userdata, offset)
+end
+
+function seek(ind, offset)
+end
+
+function input_change(ind)
+end
+]],
+
+ get_settings = function (self)
+ return { ninputs = self.ninputs, noutputs = self.noutputs, code = self.extra.code }
+ end,
+
+ run_in_localenv = function (self, f, ...)
+ local localenv = self.extra.localenv
+ local metatable = getmetatable(_G)
+ if not metatable then metatable = {} end
+ local oldni, oldi = metatable.__newindex, metatable.__index
+ metatable.__newindex = function (table, key, value)
+ localenv[key] = value
+ end
+ metatable.__index = function (table, key)
+ local l = localenv[key]
+ if l then return localenv[key] end
+ return rawget(_G, key)
+ end
+ setmetatable(_G, metatable)
+
+ if type(f) ~= "function" then f = localenv[f] end
+ local rets = { true }
+ if f then rets = { pcall(f, ...) } end
+
+ metatable.__newindex, metatable.__index = oldni, oldi
+ setmetatable(_G, metatable)
+
+ if not rets[1] then error(rets[2]) end
+ table.remove(rets, 1)
+ return unpack(rets)
+ end,
+
+ load_code = function (self, code)
+ self.extra.localenv = {
+ ninputs = self.ninputs + 0,
+ noutputs = self.noutputs + 0,
+ get_input = function(ind) return self:get_linked_input(ind) end,
+ del_output = function(ind) self:set_houtput(nil, ind) end,
+ new_output = function(ind, size, name)
+ self:set_houtput(dalos.luahandle{
+ size = size,
+ getname = function ()
+ return name
+ end,
+ do_read = function (lh, count, userdata)
+ return self:run_in_localenv("read", ind, count, userdata, lh.offset)
+ end,
+ do_seek = function (lh)
+ return self:run_in_localenv("seek", ind, lh.offset)
+ end,
+ }, ind)
+ end,
+ set_color = function(c) self.color = c self:draw() end,
+ }
+ if code and code ~= "" then
+ local f = loadstring(code)
+ if f then self:run_in_localenv(f) end
+ end
+ end,
+
+ input_change = function (self, ind)
+ self:run_in_localenv("input_change", ind)
+ end,
+
+ load_template = function (self)
+ local dlg = iup.filedlg {
+ dialogtype = "Open",
+ filter = "*.dtpl",
+ }
+ iup.Popup(dlg)
+ if dlg.status == -1 then return end
+
+ local s, v = pcall(Input, dlg.value)
+ if not s then error("Problem loading file " .. dlg.value) end
+ local f = preload(v)
+ v:destroy()
+ if not f then error("Syntax error loading file " .. dlg.value) end
+ local data, otype, tname = f()
+ if otype ~= "Lua Filter" then error("Wrong template type: " .. otype) end
+
+ self:apply_template(data.template)
+ end,
+
+ gen_template = function (self)
+ return { code = self.extra.close }
+ end,
+
+ apply_template = function (self, data)
+ self.extra.code = data.code
+ end,
+
+ configure = function (self)
+ local okay = false
+ local text = iup.text { multiline = "Yes", font = "Courier", expand = "Yes", value = self.extra.code }
+ local bok = iup.button { title = "Ok", action = function () okay = true return iup.CLOSE end }
+ local bimport = iup.button { title = "Import", action = function() self:load_template() return iup.CLOSE end }
+ local bexport = iup.button { title = "Export", action = function() self:save_template(self:gen_template()) end }
+ local busetpl = iup.button { title = "Use Template", action = function() self:use_template(dalosp.luafilter.templates) end }
+ local bcancel = iup.button { title = "Cancel", action = function () okay = false return iup.CLOSE end }
+ local dlg = iup.dialog { iup.vbox { text, iup.hbox { bok, bimport, bexport, busetpl, iup.fill{}, bcancel, normalizesize = "Horizontal" } }, title = "Code for " .. self.name, size = "600x300" }
+ local r = dlg:popup()
+-- if r ~= iup.NOERROR then return end
+ local newcode = text.value
+ if newcode and okay then
+ self.extra.code = newcode
+ self:load_code(newcode)
+ end
+ end,
+
+ activate = function (self)
+ self:run_in_localenv "activate"
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = settings and settings.ninputs
+ tab.noutputs = settings and settings.noutputs
+ tab.otype = dalos.objtype.LUA_FILTER
+ tab.configure = dalosp.luafilter.configure
+ tab.activate = dalosp.luafilter.activate
+ tab.input_change = dalosp.luafilter.input_change
+ tab.default_name = "Lua Filter"
+ tab.get_settings = dalosp.luafilter.get_settings
+ tab.ntype = "Lua Filter"
+ tab.gen_template = dalosp.luafilter.gen_template
+ tab.apply_template = dalosp.luafilter.apply_template
+ local extra = { localenv = {} }
+ extra.code = settings and settings.code
+ if not extra.code or extra.code == "" then extra.code = dalosp.luafilter.default_code end
+ local s = true
+ while not s and not tab.ninputs or not tab.noutputs do
+ s, tab.ninputs, tab.noutputs = iup.GetParam("Lua Filter", nil, "Inputs number: %i\nOutputs number: %i\n", 1, 1)
+ end
+
+ local obj = dalos.object(d, tab, extra)
+
+ obj.load_code = dalosp.luafilter.load_code
+ obj.run_in_localenv = dalosp.luafilter.run_in_localenv
+ obj:load_code(extra.code)
+
+ return obj
+ end,
+
+ register_template = function (data, tname)
+ dalosp.luafilters.templates[tname] = data
+ end,
+}
+
+dalos.luafilter = dalosp.luafilter.create
+dalos:register_obj("Lua Filter", dalos.luafilter, "Programmable", dalosp.luafilter.register_template)
diff --git a/dalos-luahandle.lua b/dalos-luahandle.lua
new file mode 100644
index 0000000..d3615fc
--- /dev/null
+++ b/dalos-luahandle.lua
@@ -0,0 +1,52 @@
+dalosp.luahandle = {
+ create = function (tab)
+ local obj = {
+ offset = 0,
+ canread = function (self) return true end,
+ canwrite = function (self) return false end,
+ canseek = function (self) return true end,
+ canwatch = function (self) return false end,
+ tell = function (self) return self.offset end,
+ getsize = function (self) return self.size end,
+ getmodif = function (self) return 0 end,
+ flush = function (self) return true end,
+ seek = function (self, offset, wheel)
+ if wheel == SEEK_SET then
+ self.offset = offset
+ elseif wheel == SEEK_CUR then
+ self.offset = self.offset + offset
+ elseif wheel == SEEK_END then
+ self.offset = self.size + offset
+ else
+ error "Unknown wheel"
+ end
+ if self.offset < 0 then self.offset = 0 end
+ if self.offset >= self.size then self.offset = self.size end
+ if self.do_seek then self:do_seek() end
+ return self.offset
+ end,
+ read = function (self, userdata, count)
+ count = math.min(count, self.size - self.offset)
+
+ if count == 0 then
+ if self.got_eof then self.lh:close() end
+ self.got_eof = true
+ return 0
+ end
+
+ self.got_eof = false
+
+ local r, t = self:do_read(count, userdata)
+ self.offset = self.offset + r
+ if self.post_read then self:post_read(r) end
+ return r, t
+ end,
+ }
+ for k, v in pairs(tab) do obj[k] = v end
+ local newh = HandleLua(obj)
+ obj.lh = newh
+ return newh
+ end,
+}
+
+dalos.luahandle = dalosp.luahandle.create
diff --git a/dalos-struct.lua b/dalos-struct.lua
new file mode 100644
index 0000000..5f157ef
--- /dev/null
+++ b/dalos-struct.lua
@@ -0,0 +1,601 @@
+local function imLoadImage(fname)
+ local f = im.FileOpen(fname)
+ local r = f:LoadImage()
+ f:Close()
+ return r
+end
+
+dalosp.struct = {
+ templates = {},
+
+ images = {
+ up = imLoadImage "12-em-up.tga",
+ down = imLoadImage "12-em-down.tga",
+ cross = imLoadImage "12-em-cross.tga",
+ plus = imLoadImage "12-em-plus.tga",
+ },
+
+ types = {
+ "int8",
+ "uint8",
+ "int16",
+ "uint16",
+ "int32",
+ "uint32",
+ "int64",
+ "uint64",
+ "float",
+ "double",
+ "nascii",
+ "asciiz",
+ },
+
+ rtypes = {
+ int8 = 1,
+ uint8 = 2,
+ int16 = 3,
+ uint16 = 4,
+ int32 = 5,
+ uint32 = 6,
+ int64 = 7,
+ uint64 = 8,
+ float = 9,
+ double = 10,
+ nascii = 11,
+ asciiz = 12,
+ },
+
+ typessizes = {
+ 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 1, -1,
+ },
+
+ get_settings = function (self)
+ return { entries = self.extra.entries }
+ end,
+
+ configure = function (self)
+ self.cfg_dlg:show()
+ end,
+
+ activate = function (self)
+ self.act_dlg:show()
+ end,
+
+ input_change = function (self, ind)
+ if ind == 1 then self:update_values() end
+ if ind == 2 then
+ local h = self:get_linked_input(2)
+ self:auto_template(dalosp.struct.templates, h:readstring())
+ end
+ end,
+
+ offset = function (self, lin)
+ local cache = self.extra.cache
+ return cache[lin]
+ end,
+
+ read_value = function (self, h, t, flags, size)
+ local v
+
+ if t == "int8" then
+ return h:read8()
+ elseif t == "uint8" then
+ return h:readU8()
+ elseif t == "int16" then
+ return h:read16()
+ elseif t == "uint16" then
+ return h:readU16()
+ elseif t == "int32" then
+ return h:read32()
+ elseif t == "uint32" then
+ return h:readU32()
+ elseif t == "int64" then
+ return h:read64()
+ elseif t == "uint64" then
+ return h:readU64()
+ elseif t == "float" then
+ return h:readFloat()
+ elseif t == "double" then
+ return h:readDouble()
+ elseif t == "asciiz" then
+ v = ""
+ local b
+ repeat
+ b = h:readU8()
+ if b ~= 0 then v = v .. string.char(b) end
+ until b == 0
+ return v
+ elseif t == "nascii" then
+ return h:readstring(size)
+ end
+
+ return 0
+ end,
+
+ update_values = function (self)
+ local h = self:get_linked_input(1)
+ self.extra.values = {}
+ self.extra.values_by_name = {}
+ if h and h:getsize() >= self.extra.size then
+ h:seek(0)
+ local v, s, t
+ for e, f in ipairs(self.extra.entries) do
+ s = f.size
+ if not tonumber(s) then
+ s = self.extra.values_by_name[s]
+ end
+ t = dalosp.struct.types[f.type]
+ if t == "asciiz" or t == "nascii" or s == 1 then
+ v = self:read_value(h, t, f.flags, s)
+ else
+ v = {}
+ for i = 1, f.size do
+ v[i] = self:read_value(h, t, f.flags, s)
+ end
+ end
+ self.extra.values[e] = v
+ self.extra.values_by_name[f.name] = v
+ end
+ self:output_selected()
+ self:output_struct()
+ else
+ self:set_houtput(nil, 1)
+ self:set_houtput(nil, 2)
+ end
+ end,
+
+ output_selected = function (self)
+ local selected = self.extra.selected
+ local cache = self.extra.cache
+ local cursor = selected and cache[selected] or -1
+ local h = self:get_linked_input(1)
+ if h and selected and selected > 0 and cursor >= 0 then
+ local field = self.extra.entries[selected].name
+ local maxsize = (cache[selected + 1] or self.extra.size) - cursor
+ h:seek(cursor)
+ local obj = {
+ h = h,
+ str = self,
+ origin = cursor,
+ field = field,
+ size = maxsize - cursor,
+ getname = function (self) return self.str.name .. ":" .. self.field end,
+ getmodif = function (self) return self.h:getmodif() end,
+ do_seek = function (self)
+ self.h:seek(self.offset + self.origin)
+ end,
+ do_read = function (self, count, userdata)
+ return self.h:read(count, userdata)
+ end,
+ }
+ self:set_houtput(dalos.luahandle(obj), 1)
+ local b = Buffer(true)
+ b:write(field .. "\n")
+ self:set_houtput(b, 3)
+ else
+ self:set_houtput(nil, 1)
+ self:set_houtput(nil, 3)
+ end
+ end,
+
+ output_struct = function (self)
+ local b = Buffer(true)
+ dumpvars(b, self.extra.values_by_name, "data")
+ self:set_houtput(b, 2)
+ end,
+
+ cacheoffset = function (self)
+ local entries = self.extra.entries
+ self.extra.cache = {}
+ local cache = self.extra.cache
+ local offset = 0
+ local got_var = false
+ local ssize
+ local vsize
+
+ for i, v in ipairs(entries) do
+ ssize = dalosp.struct.typessizes[v.type]
+ vsize = ssize == -1 or type(v.size) ~= "number"
+ if vsize then got_var = true end
+ if got_var then
+ cache[i] = -1
+ else
+ cache[i] = offset
+ end
+ if not vsize then offset = offset + ssize * v.size end
+ end
+ self.extra.size = offset
+ if self.cfg_dlg then
+ self.cfg_dlg.mx.redraw = "C10"
+ self.cfg_dlg.lsize.title = offset
+ self:update_values()
+ self.act_dlg.mx.numlin = #entries
+ self.act_dlg.mx.numlin_visible = #entries
+ self.act_dlg.mx.redraw = "All"
+ end
+ end,
+
+ isunique = function (self, name)
+ for _, v in ipairs(self.extra.entries) do
+ if name == v.name then return false end
+ end
+ return true
+ end,
+
+ getunique = function (self, lin)
+ local newname = "Field" .. lin
+ local base_newname = newname
+ local i = 1
+ while not self:isunique(newname) do
+ newname = base_newname .. "." .. i
+ i = i + 1
+ end
+ return newname
+ end,
+
+ insert_line = function (self, lin)
+ if not lin then lin = (#self.extra.entries + 1) end
+ local name = self:getunique(lin)
+ table.insert(self.extra.entries, lin, { name = name, type = 1, size = 1 })
+ self:cacheoffset()
+ local mx = self.cfg_dlg.mx
+ mx.numlin = mx.numlin + 1
+ mx.numlin_visible = mx.numlin_visible + 1
+ end,
+
+ remove_line = function (self, lin)
+ table.remove(self.extra.entries, lin)
+ self:cacheoffset()
+ local mx = self.cfg_dlg.mx
+ mx.numlin = mx.numlin - 1
+ mx.numlin_visible = mx.numlin_visible - 1
+ end,
+
+ line_up = function (self, lin)
+ if lin == 1 then return iup.DEFAULT end
+ local entries = self.extra.entries
+ local old_lin = entries[lin]
+ table.remove(entries, lin)
+ table.insert(entries, lin - 1, old_lin)
+ self:cacheoffset()
+ local mx = self.cfg_dlg.mx
+ mx.redraw = "L" .. (lin - 1)
+ mx.redraw = "L" .. lin
+ end,
+
+ line_down = function (self, lin)
+ local entries = self.extra.entries
+ if lin == #entries then return iup.DEFAULT end
+ local old_lin = entries[lin]
+ table.remove(entries, lin)
+ table.insert(entries, lin + 1, old_lin)
+ self:cacheoffset()
+ local mx = self.cfg_dlg.mx
+ mx.redraw = "L" .. lin
+ mx.redraw = "L" .. (lin + 1)
+ end,
+
+ gen_template = function (self)
+ return self:get_settings()
+ end,
+
+ apply_template = function (self, data)
+ self.extra.entries = data.entries
+ self:cacheoffset()
+ end,
+
+ get_field_value = function (self, lin)
+ local v = self.extra.values[lin]
+ if type(v) == "table" then
+ local r = nil
+ for k, sv in ipairs(v) do
+ if not r then
+ r = sv
+ else
+ r = r .. ", " .. sv
+ end
+ end
+
+ return "[" .. (r or " ") .."]"
+ else
+ return v or ""
+ end
+ end,
+
+ cfg_draw_cb = function (self, lin, col, x1, x2, y1, y2, cv)
+ if col == 1 then
+ dalosp.struct.images.plus:cdCanvasPutImageRect(cv, x1 + 3, y2 + 5, 12, 12, 0, 12, 0, 12)
+ return iup.DEFAULT
+ elseif col == 2 and lin ~= 0 then
+ dalosp.struct.images.cross:cdCanvasPutImageRect(cv, x1 + 3, y2 + 5, 12, 12, 0, 12, 0, 12)
+ return iup.DEFAULT
+ elseif col == 3 and lin ~= 0 and lin ~= 1 then
+ dalosp.struct.images.up:cdCanvasPutImageRect(cv, x1 + 3, y2 + 5, 12, 12, 0, 12, 0, 12)
+ return iup.DEFAULT
+ elseif col == 4 and lin ~= 0 and lin ~= #self.struct.extra.entries then
+ dalosp.struct.images.down:cdCanvasPutImageRect(cv, x1 + 3, y2 + 5, 12, 12, 0, 12, 0, 12)
+ return iup.DEFAULT
+ end
+
+ return iup.IGNORE
+ end,
+
+ cfg_click_cb = function (self, lin, col, status)
+ if col == 1 and lin == 0 then return self.struct:insert_line() end
+ if lin == 0 then return iup.DEFAULT end
+
+ if col == 1 then
+ self.struct:insert_line(lin)
+ elseif col == 2 then
+ self.struct:remove_line(lin)
+ elseif col == 3 then
+ self.struct:line_up(lin)
+ elseif col == 4 then
+ self.struct:line_down(lin)
+ elseif col == 11 then
+ -- edit flags
+ end
+ end,
+
+ cfg_value_cb = function (self, lin, col)
+ if lin == 0 then
+ if col == 5 then
+ return "Name"
+ elseif col == 6 then
+ return "Type"
+ elseif col == 7 then
+ return "Size"
+ elseif col == 8 then
+ return "Enum"
+ elseif col == 9 then
+ return "Value Check"
+ elseif col == 10 then
+ return "Offset"
+ elseif col == 11 then
+ return "Flags"
+ end
+ return ""
+ end
+
+ local entries = self.struct.extra.entries
+
+ if col == 5 then
+ return entries[lin].name
+ elseif col == 6 then
+ return dalosp.struct.types[entries[lin].type]
+ elseif col == 7 then
+ return entries[lin].size
+ elseif col == 10 then
+ local off = self.struct:offset(lin)
+ if off == -1 then return "" end
+ return off
+ elseif col == 11 then
+ -- flags
+ end
+
+ return ""
+ end,
+
+ cfg_value_edit_cb = function (self, lin, col, newval)
+ local entries = self.struct.extra.entries
+
+ if col == 5 then
+ entries[lin].name = newval
+ self.struct:output_selected()
+ self.struct:output_struct()
+ elseif col == 6 then
+ entries[lin].type = dalosp.struct.rtypes[newval]
+ self.struct:cacheoffset()
+ elseif col == 7 then
+ local nnewval = tonumber(newval)
+ if nnewval then newval = nnewval end
+ entries[lin].size = newval
+ self.struct:cacheoffset()
+ elseif col == 8 then
+ -- enum
+ elseif col == 9 then
+ -- value check
+ end
+ self.struct.act_dlg.mx.redraw = "All"
+ end,
+
+ cfg_dropcheck_cb = function (self, lin, col)
+ return col == 6 and iup.DEFAULT or iup.IGNORE
+ end,
+
+ cfg_edition_cb = function (self, lin, col, mode, update)
+ if mode == 1 then
+ return (col >= 5 and col <= 7) and iup.DEFAULT or iup.IGNORE
+ else
+ local newval = self.value
+ if update == 0 then return iup.DEFAULT end
+ if col == 5 then
+ if not self.struct:isunique(newval) then return iup.IGNORE end
+ elseif col == 6 then
+ -- do a check on the dropdown ? I don't think so
+ elseif col == 7 then
+ if not tonumber(newval) and self.struct:isunique(newval) then return iup.IGNORE end
+ elseif col == 8 then
+ -- enum
+ elseif col == 9 then
+ -- value check
+ end
+ return iup.DEFAULT
+ end
+ end,
+
+ cfg_drop_cb = function (self, drop, lin, col)
+ if col ~= 6 then return iup.IGNORE end
+
+ for i, v in ipairs(dalosp.struct.types) do
+ drop[i] = v
+ end
+ drop.value = self.previousvalue
+ drop.visible_items = 15
+
+ return iup.DEFAULT
+ end,
+
+ act_value_cb = function (self, lin, col)
+ if lin == 0 then if col == 1 then return "Field" elseif col == 2 then return "Value" end end
+ if col == 0 then return nil end
+
+ local entry = self.struct.extra.entries[lin]
+
+ if col == 1 then
+ return entry.name
+ else
+ return self.struct:get_field_value(lin)
+ end
+ end,
+
+ act_click_cb = function (self, lin, col, status)
+ self.struct.extra.selected = lin
+ self.struct:output_selected()
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 2
+ tab.noutputs = 3
+ tab.otype = dalos.objtype.LUA_VIEWER
+ tab.configure = dalosp.struct.configure
+ tab.activate = dalosp.struct.activate
+ tab.input_change = dalosp.struct.input_change
+ tab.get_settings = dalosp.struct.get_settings
+ tab.gen_template = dalosp.struct.gen_template
+ tab.apply_template = dalosp.struct.apply_template
+ tab.draw = function (self, cv, x, y, w, h)
+ dalosp.object.default_draw(self, cv, x, y, w, h)
+ end
+ tab.default_name = "Struct"
+ tab.ntype = "Struct"
+
+ local extra = { }
+ if not settings then settings = {} end
+ local entries = settings.entries or {}
+ extra.entries = entries
+
+ local obj = dalos.object(d, tab, extra)
+
+ obj.insert_line = dalosp.struct.insert_line
+ obj.remove_line = dalosp.struct.remove_line
+ obj.line_up = dalosp.struct.line_up
+ obj.line_down = dalosp.struct.line_down
+ obj.offset = dalosp.struct.offset
+ obj.cacheoffset = dalosp.struct.cacheoffset
+ obj.isunique = dalosp.struct.isunique
+ obj.getunique = dalosp.struct.getunique
+ obj.get_field_value = dalosp.struct.get_field_value
+ obj.update_values = dalosp.struct.update_values
+ obj.read_value = dalosp.struct.read_value
+ obj.output_selected = dalosp.struct.output_selected
+ obj.output_struct = dalosp.struct.output_struct
+
+ local cmx = iup.matrix {
+ numcol = 11,
+ numcol_visible = 11,
+ usetitlesize = "Yes",
+ rasterwidth1 = 12,
+ rasterwidth2 = 12,
+ rasterwidth3 = 12,
+ rasterwidth4 = 12,
+ rasterwidth5 = 120,
+ rasterwidth6 = 80,
+ rasterwidth7 = 80,
+ rasterwidth8 = 80,
+ rasterwidth9 = 120,
+ rasterwidth10 = 40,
+ rasterwidth11 = 60,
+ resizematrix = "Yes",
+ readonly = "No",
+ struct = obj,
+ draw_cb = dalosp.struct.cfg_draw_cb,
+ value_cb = dalosp.struct.cfg_value_cb,
+ value_edit_cb = dalosp.struct.cfg_value_edit_cb,
+ dropcheck_cb = dalosp.struct.cfg_dropcheck_cb,
+ drop_cb = dalosp.struct.cfg_drop_cb,
+ edition_cb = dalosp.struct.cfg_edition_cb,
+ click_cb = dalosp.struct.cfg_click_cb,
+ }
+ local amx = iup.matrix {
+ numcol = 2,
+ numcol_visible = 2,
+ usetitlesize = "Yes",
+ rasterwidth1 = 120,
+ rasterwidth2 = 120,
+ readonly = "Yes",
+ resizematrix = "Yes",
+ struct = obj,
+ value_cb = dalosp.struct.act_value_cb,
+ click_cb = dalosp.struct.act_click_cb,
+ }
+ local lsize = iup.label { title = "0", expand = "Horizontal", }
+
+ obj.cfg_dlg = iup.dialog {
+ iup.vbox {
+ iup.hbox {
+ iup.label { title = "Struct size: " },
+ lsize,
+ },
+ cmx,
+ iup.hbox {
+ iup.fill {},
+ iup.button {
+ title = "Ok",
+ action = function (self) return iup.CLOSE end,
+ },
+ iup.button {
+ title = "Import",
+ action = function() obj:load_template() return iup.CLOSE end,
+ },
+ iup.button {
+ title = "Export",
+ action = function() obj:save_template(self:gen_template()) end,
+ },
+ iup.button {
+ title = "Use Template",
+ action = function() obj:use_template(dalsop.struct.templates) end,
+ },
+ iup.button {
+ title = "Change name",
+ action = function() local s, n = iup.GetParam("Change name", nil, "Name: %s\n", obj.name) if s then obj.name = n end end
+ },
+ iup.fill {},
+ iup.button {
+ title = "Close",
+ action = function() return iup.CLOSE end,
+ },
+ },
+ },
+
+ size = "500x220",
+ mx = cmx,
+ lsize = lsize,
+ title = obj.name .. " configuration",
+ }
+
+ obj.act_dlg = iup.dialog {
+ amx,
+ size = "250x120",
+ mx = amx,
+ title = obj.name,
+ }
+
+ if entries then
+ obj.cfg_dlg.mx.numlin = #entries
+ obj.cfg_dlg.mx.numlin_visible = #entries
+ obj.act_dlg.mx.numlin = #entries
+ obj.act_dlg.mx.numlin_visible = #entries
+ end
+ obj:cacheoffset()
+
+ return obj
+ end,
+
+ register_template = function (data, tname)
+ dalosp.struct.templates[tname] = data
+ end,
+}
+
+dalos.struct = dalosp.struct.create
+dalos:register_obj("Struct", dalos.struct, "Programmable", dalosp.struct.register_template)
diff --git a/dalos-tee.lua b/dalos-tee.lua
new file mode 100644
index 0000000..b5193c0
--- /dev/null
+++ b/dalos-tee.lua
@@ -0,0 +1,50 @@
+dalosp.tee = {
+ NTEE = 16,
+
+ set_out = function (self, h, ind)
+ local name = h:getname()
+ local obj = {
+ h = h,
+ size = h:getsize(),
+ getname = function () return name end,
+ do_read = function (self, count, userdata)
+ self.h:seek(self.offset, SEEK_SET)
+ return self.h:read(count, userdata)
+ end,
+ }
+ self:set_houtput(dalos.luahandle(obj), ind)
+ end,
+
+ input_change = function (self, ind)
+ local h = self:get_linked_input(1)
+ if h then
+ self.color = cd.GREEN
+ for ind = 1, 16 do self:set_out(h, ind) end
+ self.dcanvas:draw()
+ else
+ self.color = cd.YELLOW
+ for i = 1, dalosp.tee.NTEE do
+ self:set_houtput(nil, i)
+ end
+ self.dcanvas:draw()
+ end
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 1
+ tab.noutputs = dalosp.tee.NTEE
+ tab.otype = dalos.objtype.LUA_FILTER
+ tab.input_change = dalosp.tee.input_change
+ tab.default_name = "Tee"
+ tab.ntype = "Tee"
+
+ local obj = dalos.object(d, tab)
+
+ obj.set_out = dalosp.tee.set_out
+
+ return obj
+ end,
+}
+
+dalos.tee = dalosp.tee.create
+dalos:register_obj("Tee", dalos.tee, "Basic Filters")
diff --git a/dalos-textbuffer.lua b/dalos-textbuffer.lua
new file mode 100644
index 0000000..2bda77f
--- /dev/null
+++ b/dalos-textbuffer.lua
@@ -0,0 +1,35 @@
+dalosp.textbuffer = {
+ get_settings = function (self)
+ return { text = self.extra.text }
+ end,
+
+ activate = function (self)
+ local text = self.extra.text or ""
+ text = iup.GetText(self.name, text)
+ if text then
+ self.extra.text = text
+ local b = Buffer(true)
+ b:write(text)
+ self:set_houtput(b)
+ end
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 0
+ tab.noutputs = 1
+ tab.otype = dalos.objtype.HANDLE
+ tab.activate = dalosp.textbuffer.activate
+ tab.default_name = "Text Buffer"
+ tab.ntype = "Text Buffer"
+ tab.get_settings = dalosp.textbuffer.get_settings
+ local extra = { }
+ if settings then extra.text = settings.text end
+
+ local obj = dalos.object(d, tab, extra)
+
+ return obj
+ end,
+}
+
+dalos.textbuffer = dalosp.textbuffer.create
+dalos:register_obj("Text Buffer", dalos.textbuffer, "Basic Inputs")
diff --git a/dalos-textview.lua b/dalos-textview.lua
new file mode 100644
index 0000000..2bd0be5
--- /dev/null
+++ b/dalos-textview.lua
@@ -0,0 +1,53 @@
+dalosp.textview = {
+ get_settings = function (self)
+ return { }
+ end,
+
+ input_change = function (self)
+ local h = self:get_linked_input(1)
+
+ if h then
+ self.extra.txt.value = h:readfile()
+ else
+ self.extra.txt.value = ""
+ end
+ end,
+
+ activate = function (self)
+ self.extra.dlg:show()
+ end,
+
+ create = function (d, tab, settings)
+ tab.ninputs = 1
+ tab.noutputs = 0
+ tab.otype = dalos.objtype.LUA_VIEWER
+ tab.activate = dalosp.textview.activate
+ tab.input_change = dalosp.textview.input_change
+ tab.default_name = "Text View"
+ tab.ntype = "Text View"
+ tab.get_settings = dalosp.textview.get_settings
+ local extra = { }
+
+ local obj = dalos.object(d, tab, extra)
+
+ local txt = iup.text {
+ multiline = "Yes",
+ readonly = "Yes",
+ expand = "Yes",
+ font = "Courier, 8"
+ }
+ local dlg = iup.dialog {
+ txt,
+ size = "320x200",
+ title = obj.name,
+ shrink = "Yes",
+ }
+ extra.dlg = dlg
+ extra.txt = txt
+
+ return obj
+ end,
+}
+
+dalos.textview = dalosp.textview.create
+dalos:register_obj("Text View", dalos.textview, "Basic Viewers")
diff --git a/dalos.lua b/dalos.lua
index 4e4624a..d0fcd88 100644
--- a/dalos.lua
+++ b/dalos.lua
@@ -2,22 +2,62 @@ loadmodule "luaiup"
loadmodule "luahandle"
loadmodule "lualibs"
+--[[
+load "indent.lua"
+
+function testIndenter(i)
+ local lib = IndentationLib
+ local str = ""
+ local inp = Input "dalos.lua"
+ str = inp:readfile()
+
+ local colorTable = lib.defaultColorTable
+ print(lib.indentCode(str, 4, colorTable, i))
+end
+
+testIndenter()
+]]--
+
load "iupe-dbuffer.lua"
-load "iupe-hexview.lua"
-load "iupe-hexview-toolbox.lua"
load "iupe-tview.lua"
if not dalosp then dalosp = {} end
if not dalos then dalos = {} end
-dalos.objects = {}
+dalos.objectstypes = {}
+dalos.objectstypes_by_name = {}
+
+dalosp.NORTH = 1
+dalosp.SOUTH = 2
+dalosp.WEST = 3
+dalosp.EAST = 4
+dalosp.cross = { }
-function dalos:register_obj(name, constructor)
- table.insert(self.objects, { name = name, constructor = constructor })
- if self.activemenu then
- self.activemenu:update_objects()
+dalos.version = { MAJOR = 0, MINOR = 1, suffix = "alpha" }
+dalos.version.string = dalos.version.MAJOR .. "." .. dalos.version.MINOR .. dalos.version.suffix
+
+function dalos:register_obj(name, constructor, category, registertemplate)
+ if self.objectstypes_by_name[name] then
+ error("An object type of that name already exists: " .. name)
+ end
+ table.insert(self.objectstypes, { name = name, constructor = constructor, counter = 1, category = category, registertemplate = registertemplate })
+ self.objectstypes_by_name[name] = #self.objectstypes
+ if self.active_menu then
+ self.active_menu:update_objects()
end
end
+function dalos:clean()
+ local d = dalos.active_canvas
+ for k, v in ipairs(d.objects) do
+ for ind = 1, v.obj.noutputs do
+ d:destroylink(v, ind)
+ end
+ end
+
+ while #d.objects ~= 0 do table.remove(d.objects) end
+ d.objects = {}
+end
+
dalosp.canvas = {
DARK_WHITE = cd.EncodeColor(224, 224, 224),
BEZIER_CTRL_LEN = 40,
@@ -85,6 +125,30 @@ dalosp.canvas = {
cv:Line(x1, iy(y1), x2, iy(y1))
cv:Line(x1 + 1, iy(y1 + 1), x2 - 1, iy(y1 + 1))
cv:Line(x1 + 2, iy(y1 + 2), x2 - 2, iy(y1 + 2))
+
+ local f, st, si = cv:GetFont()
+ cv:Font("Helvetica", cd.PLAIN, 10)
+
+ cv:Foreground(cd.BLACK)
+ cv:TextOrientation(0)
+ if dalosp.cross.north then
+ cv:TextAlignment(cd.NORTH)
+ cv:Text(x, iy(y1 + 3), dalosp.cross.north.name)
+ end
+ cv:TextAlignment(cd.SOUTH)
+ if dalosp.cross.south then
+ cv:Text(x, iy(y2 - 3), dalosp.cross.south.name)
+ end
+ if dalosp.cross.west then
+ cv:TextOrientation(270)
+ cv:Text(x1 + 3, iy(y), dalosp.cross.west.name)
+ end
+ if dalosp.cross.east then
+ cv:TextOrientation(90)
+ cv:Text(x2 - 3, iy(y), dalosp.cross.east.name)
+ end
+
+ cv:Font(f, st, si)
end,
draw = function (self)
@@ -120,6 +184,18 @@ dalosp.canvas = {
self:draw()
end,
+ delobj = function (self, ind)
+ local obj = self.objects[ind]
+ for i = 1, obj.obj.noutputs do
+ self:destroylink(obj, i)
+ end
+ for i = 1, obj.obj.ninputs do
+ self:destroylink_dst(obj, i)
+ end
+ table.remove(self.objects, ind)
+ self:draw()
+ end,
+
findobj = function (self, x, y)
local obj, ind
@@ -152,7 +228,7 @@ dalosp.canvas = {
end,
focus_cb = function (self, focus)
- if focus == 0 then self:button_cb() end
+ if focus == 0 and (self.stateful.rghtbutton or self.stateful.leftbutton) then self:button_cb() end
end,
stypes = {
@@ -162,10 +238,20 @@ dalosp.canvas = {
},
setstatus = function (self, stype, msg)
- -- todo: add a status line
+ local s = dalos.active_status
+ if not s then return end
+ if stype == dalos.stypes.INFO then
+ s.square.bgcolor = "0 255 0"
+ elseif stype == dalos.stypes.WARNING then
+ s.square.bgcolor = "255 255 0"
+ elseif stype == dalos.stypes.ERROR then
+ s.square.bgcolor = "255 0 0"
+ end
+ s.label.title = msg
end,
motion_cb = function (self, x, y, status)
+ self.stateful.mousepos = { x = x, y = y }
if self.stateful.panning then
local ox, oy = self.ox, self.oy
local dx, dy = x - ox, y - oy
@@ -183,7 +269,7 @@ dalosp.canvas = {
if linking.obj.noutputs >= 1 then
self.stateful.linking = linking
else
- self:setstatus(dalosp.canvas.stypes.ERROR, "Can't link: origin object doesn't have any output")
+ self:setstatus(dalos.stypes.ERROR, "Can't link: origin object doesn't have any output")
self.stateful.leftclk = nil
linking = nil
got_error = true
@@ -213,9 +299,11 @@ dalosp.canvas = {
end
end,
- createlink = function (self, src, dst)
- local oldsrc = src.obj.outputs[src.obj.curoutput]
- local olddst = dst.obj.inputs[dst.obj.curinput]
+ createlink = function (self, src, dst, srcind, dstind)
+ if not srcind then srcind = src.obj.curoutput end
+ if not dstind then dstind = dst.obj.curinput end
+ local oldsrc = src.obj.outputs[srcind]
+ local olddst = dst.obj.inputs[dstind]
if oldsrc then
oldsrc.obj.obj.inputs[oldsrc.ind] = nil
oldsrc.obj.obj:input_change(oldsrc.ind)
@@ -224,23 +312,36 @@ dalosp.canvas = {
olddst.obj.obj.outputs[olddst.ind] = nil
olddst.obj.obj:output_change(olddst.ind)
end
- src.obj.outputs[src.obj.curoutput] = { obj = dst, ind = dst.obj.curinput }
- dst.obj.inputs[dst.obj.curinput] = { obj = src, ind = src.obj.curoutput }
- src.obj:output_change(src.obj.curoutput)
- dst.obj:input_change(dst.obj.curinput)
+ src.obj.outputs[src.obj.curoutput] = { obj = dst, ind = dstind }
+ dst.obj.inputs[dst.obj.curinput] = { obj = src, ind = srcind }
+ src.obj:output_change(srcind)
+ dst.obj:input_change(dstind)
end,
- destroylink = function (self, src)
- local oldsrc = src.obj.outputs[src.obj.curoutput]
+ destroylink = function (self, src, ind)
+ if not ind then ind = src.obj.curoutput end
+ local oldsrc = src.obj.outputs[ind]
if oldsrc then
- src.obj.outputs[src.obj.curoutput] = nil
- src.obj:output_change(src.obj.curoutput)
+ src.obj.outputs[ind] = nil
+ src.obj:output_change(ind)
oldsrc.obj.obj.inputs[oldsrc.ind] = nil
oldsrc.obj.obj:input_change(oldsrc.ind)
end
end,
+ destroylink_dst = function (self, dst, ind)
+ if not ind then ind = dst.obj.curinput end
+ local olddst = dst.obj.inputs[ind]
+ if olddst then
+ dst.obj.inputs[ind] = nil
+ dst.obj:input_change(ind)
+
+ olddst.obj.obj.outputs[olddst.ind] = nil
+ olddst.obj.obj:output_change(olddst.ind)
+ end
+ end,
+
button_cb = function (self, button, pressed, x, y, status)
if not pressed then pressed = 0 end
if not x then x = self.ox end
@@ -256,23 +357,25 @@ dalosp.canvas = {
self.stateful.leftclk = obj
table.remove(self.objects, ind)
table.insert(self.objects, obj)
- self.ox, self.oy = x, y
- self.bx, self.by = x, y
- self:draw()
end
+ self.ox, self.oy = x, y
+ self.bx, self.by = x, y
+ self:draw()
end
else
if not self.stateful.linking and self.stateful.leftclk and not self.stateful.dragging then
+ self.stateful.leftbutton = nil
self.stateful.leftclk.obj:activate()
elseif self.stateful.linking then
local dest = self:findobj(x,y)
if not dest then
self:destroylink(self.stateful.linking)
elseif dest == self.stateful.linking then
- self:setstatus(dalosp.canvas.stypes.ERROR, "Can't link: origin is the same as destination")
+ self:setstatus(dalos.stypes.ERROR, "Can't link: origin is the same as destination")
elseif dest.obj.ninputs <= 0 then
- self:setstatus(dalosp.canvas.stypes.ERROR, "Can't link: destination has no input")
+ self:setstatus(dalos.stypes.ERROR, "Can't link: destination has no input")
else
+ self:setstatus(dalos.stypes.INFO, "Linking '" .. self.stateful.linking.obj.name .. "' and '" .. dest.obj.name .. "'")
self:createlink(self.stateful.linking, dest)
end
self.stateful.linking = nil
@@ -297,22 +400,38 @@ dalosp.canvas = {
self.stateful.rghtclk = obj
table.remove(self.objects, ind)
table.insert(self.objects, obj)
- self.ox, self.oy = x, y
- self.bx, self.by = x, y
- self:draw()
end
+ self.ox, self.oy = x, y
+ self.bx, self.by = x, y
+ self:draw()
end
else
if not self.stateful.moving and self.stateful.rghtclk and not self.stateful.dragging then
+ self.stateful.rghtbutton = nil
self.stateful.rghtclk.obj:configure()
self:draw()
elseif self.menu.x then
- -- activate X menu operation
+ local dx, dy = x - self.menu.x, y - self.menu.y
+ local obj
+ if math.abs(dx) > math.abs(dy) then
+ if dx < 0 then
+ obj = dalosp.cross.west
+ else
+ obj = dalosp.cross.east
+ end
+ else
+ if dy < 0 then
+ obj = dalosp.cross.north
+ else
+ obj = dalosp.cross.south
+ end
+ end
+ if obj then dalosp.menu.add_object(self, obj, self.menu.x, self.menu.y) end
self.menu.x = nil
self.menu.y = nil
self:draw()
elseif self.stateful.moving then
- -- check for the trash can
+ -- dropped somewhere... do something useful here ?
end
self.stateful.panning = nil
self.stateful.moving = nil
@@ -326,6 +445,9 @@ dalosp.canvas = {
wheel_cb = function (self, delta, x, y, status)
local obj = self:findobj(x, y)
+ delta = -delta
+ if delta > 0 then delta = math.floor(delta + 0.5) else delta = -math.floor(-delta + 0.5) end
+
if obj then
if iup.isshift(status) then
obj.obj:change_curoutput(delta)
@@ -339,10 +461,22 @@ dalosp.canvas = {
self:draw()
end,
+ keypress_cb = function (self, c, press)
+ if press ~= 1 then return end
+ local obj, ind = self:findobj(self.stateful.mousepos.x, self.stateful.mousepos.y)
+ if c == iup.K_cS then
+ if obj then self:delobj(ind) end
+ elseif c == iup.K_n then
+ if not obj then return end
+ local s, newname = iup.GetParam("Renaming", nil, "Set name: %s\n", obj.obj.name)
+ if s and newname then obj.obj.name = newname end
+ self:draw()
+ end
+ end,
+
create = function (tab)
tab.border = "No"
tab.expand = "Yes"
- tab.shrink = "Yes"
tab.minsize = "1x1"
tab.rastersize = "1x1"
local r = iup.canvas(tab)
@@ -355,7 +489,9 @@ dalosp.canvas = {
r.motion_cb = dalosp.canvas.motion_cb
r.button_cb = dalosp.canvas.button_cb
r.wheel_cb = dalosp.canvas.wheel_cb
+ r.keypress_cb = dalosp.canvas.keypress_cb
r.addobj = dalosp.canvas.addobj
+ r.delobj = dalosp.canvas.delobj
r.findobj = dalosp.canvas.findobj
r.moveobj = dalosp.canvas.moveobj
r.setobjplace = dalosp.canvas.setobjplace
@@ -363,6 +499,7 @@ dalosp.canvas = {
r.setstatus = dalosp.canvas.setstatus
r.createlink = dalosp.canvas.createlink
r.destroylink = dalosp.canvas.destroylink
+ r.destroylink_dst = dalosp.canvas.destroylink_dst
r.drawlink = dalosp.canvas.drawlink
r.drawxmenu = dalosp.canvas.drawxmenu
r.origin = { x = 0, y = 0 }
@@ -378,6 +515,172 @@ dalosp.canvas = {
}
dalosp.menu = {
+ action_new = function (self)
+ local d = dalos.active_canvas
+ dalos:clean()
+
+ d:setstatus(dalos.stypes.INFO, "Workspace cleaned")
+ end,
+
+ action_load = function (self)
+ local dlg = iup.filedlg {
+ dialogtype = "Open",
+ filter = "*.dalos"
+ }
+ iup.Popup(dlg)
+ if dlg.status == -1 then return end
+
+ local s, v = pcall(Input, dlg.value)
+ if not s then error("Problem loading file " .. dlg.value) end
+ local f = preload(v)
+ v:destroy()
+ if not f then error("Syntax error loading file " .. dlg.value) end
+ local data = f()
+ local tlup = dalos.objectstypes_by_name
+ local ot = dalos.objectstypes
+ local d = dalos.active_canvas
+ local lup = {}
+ for k, v in ipairs(data.objects) do
+ if not tlup[v.ntype] then error("Object " .. v.ntype .. " isn't declared") end
+ end
+ if data.imports then
+ for i, v in ipairs(data.imports) do
+ dalosp.menu.load_file(v)
+ end
+ end
+ dalos:clean()
+ for k, v in ipairs(data.objects) do
+ local tab = { x = v.x, y = v.y, name = v.name }
+ local o = ot[tlup[v.ntype]].constructor(d, tab, v.settings)
+ for iobj, obj in ipairs(d.objects) do
+ if obj.obj == o then
+ lup[iobj] = obj
+ end
+ end
+ end
+ for k, v in ipairs(data.links) do
+ if not lup[v.src] then error("Can't find object for id src " .. v.src) end
+ if not lup[v.dst] then error("Can't find object for id dst " .. v.dst) end
+ d:createlink(lup[v.src], lup[v.dst], v.isrc, v.idst)
+ end
+ if data.cross then
+ dalosp.cross = {}
+ if data.cross.north then dalosp.cross.north = tlup[data.cross.north] end
+ if data.cross.south then dalosp.cross.south = tlup[data.cross.south] end
+ if data.cross.west then dalosp.cross.west = tlup[data.cross.west] end
+ if data.cross.east then dalosp.cross.east = tlup[data.cross.east] end
+ end
+
+ d:setstatus(dalos.stypes.INFO, "Properly loaded")
+ end,
+
+ action_save = function(self)
+ local s_obj = { }
+ if not dalos.active_canvas then return end
+ local d = dalos.active_canvas
+ for i, v in ipairs(d.objects) do
+ s_obj[i] = { x = v.x, y = v.y, name = v.obj.name, ntype = v.obj.ntype, settings = v.obj:get_settings(), lookup = v }
+ end
+ local s_links = { }
+ for iobj, obj in ipairs(d.objects) do
+ for iout, out in pairs(obj.obj.outputs) do
+ for ilookup, lobj in ipairs(s_obj) do
+ if lobj.lookup == out.obj then
+ table.insert(s_links, { src = iobj, dst = ilookup, isrc = iout, idst = out.ind })
+ end
+ end
+ end
+ end
+ for i, v in ipairs(s_obj) do
+ v.lookup = nil
+ end
+ local s_cross = { }
+ if dalosp.cross.north then s_cross.north = dalosp.cross.north.name end
+ if dalosp.cross.sorth then s_cross.sorth = dalosp.cross.sorth.name end
+ if dalosp.cross.west then s_cross.west = dalosp.cross.west.name end
+ if dalosp.cross.east then s_cross.east = dalosp.cross.east.name end
+ local save = { objects = s_obj, links = s_links, cross = s_cross, imports = dalosp.imports }
+ local dlg = iup.filedlg {
+ dialogtype = "Save",
+ dalos = "*.dalos",
+ }
+ iup.Popup(dlg)
+ if dlg.status ~= -1 then
+ local s, v = pcall(Output, dlg.value)
+ if s then
+ v:write "---- Dalos save\nlocal "
+ dumpvars(v, dalos.version, "version")
+ v:write "if dalos.version.MAJOR < version.MAJOR or dalos.version.MAJOR == version.MAJOR and dalos.version.MINOR < version.MINOR then error 'Dalos version too old for this save.' end\n\nlocal "
+ dumpvars(v, save, "save")
+ v:write "return save"
+ v:destroy()
+ else
+ error("Failed opening " .. dlg.value .. " for writing")
+ end
+ end
+
+ d:setstatus(dalos.stypes.INFO, "Properly saved")
+ end,
+
+ load_file = function (file)
+ local s, v = pcall(load, file)
+ if not s then return end
+ if not dalosp.imports then dalosp.imports = {} end
+ for i, v in ipairs(dalosp.imports) do
+ if v == file then return end
+ end
+ table.insert(dalosp.imports, file)
+ end,
+
+ action_import = function (self)
+ local dlg = iup.filedlg {
+ dialogtype = "Open",
+ filter = "*.lua",
+ }
+ iup.Popup(dlg)
+ if dlg.status == -1 then return end
+
+ local d = dalos.active_canvas
+ dalosp.menu.load_file(dlg.value)
+ d:setstatus(dalos.stypes.INFO, "Properly imported")
+ end,
+
+ action_reload = function (self)
+ if not dalosp.imports then return end
+
+ for i, v in ipairs(dalosp.imports) do
+ pcall(load, v)
+ end
+ d:setstatus(dalos.stypes.INFO, "Properly reloaded all imported files")
+ end,
+
+ action_load_template = function (self)
+ local dlg = iup.filedlg {
+ dialogtype = "Open",
+ filter = "*.dtpl",
+ }
+ iup.Popup(dlg)
+ if dlg.status == -1 then return end
+
+ local s, v = pcall(Input, dlg.value)
+ if not s then error("Problem loading file " .. dlg.value) end
+ local f = preload(v)
+ v:destroy()
+ if not f then error("Syntax error loading file " .. dlg.value) end
+ local t = f()
+ local data, otype, tname = t.data, t.otype, t.tname
+
+ local tobj = dalos.objectstypes_by_name[otype]
+ if not tobj then error("Unknown template object type: " .. otype) end
+ tobj = dalos.objectstypes[tobj]
+
+ dalos:register_obj(otype .. "::" .. tname, function(d, tab) tobj.constructor(d, tab, data) end, "Template")
+ if tobj.registertemplate then tobj.registertemplate(data, tname) end
+ local d = dalos.active_canvas
+
+ d:setstatus(dalos.stypes.INFO, "Template properly loaded")
+ end,
+
action_exit = function (self)
return iup.CLOSE
end,
@@ -388,21 +691,51 @@ dalosp.menu = {
ButtonDefault = "1",
Buttons = "OK",
Title = "About",
- Value = 'DALOS (c) 2009-2010 Nicolas "Pixel" Noble.\nThis is free software with ABSOLUTELY NO WARRANTY.\nPlease look at the COPYRIGHT file for details.',
+ Value = 'DALOS ' .. dalos.version.string .. ' (c) 2009-2010 Nicolas "Pixel" Noble.\nThis is free software with ABSOLUTELY NO WARRANTY.\nPlease look at the COPYRIGHT file for details.',
}
dlg:popup()
return iup.DEFAULT
end,
update_objects = function (self)
- if dalos.dlg then
- local newmenu = dalos.menu {}
+ local d = dalos.active_canvas
+ if d and d.dialog then
+ local newmenu = dalos.menu(dalos.active_canvas)
-- copy anything from self to newmenu ? *shrug*
- dalos.dlg.menu = newmenu
+ d.dialog.menu = newmenu
end
end,
- create = function (tab)
+ add_object = function (canvas, object, x, y)
+ object.constructor(canvas, { counter = object.counter, x = (x or 25) + 0, y = (y or 25) + 0}, {})
+ object.counter = object.counter + 1
+ end,
+
+ set_cross = function (canvas, object, dir)
+ if dir == dalosp.NORTH then
+ dalosp.cross.north = object
+ elseif dir == dalosp.SOUTH then
+ dalosp.cross.south = object
+ elseif dir == dalosp.EAST then
+ dalosp.cross.east = object
+ elseif dir == dalosp.WEST then
+ dalosp.cross.west = object
+ end
+ end,
+
+ create = function (canvas, tab)
+ local item_new = iup.item { title = "New" }
+ item_new.action = dalosp.menu.action_new
+ local item_load = iup.item { title = "Load workspace" }
+ item_load.action = dalosp.menu.action_load
+ local item_save = iup.item { title = "Save workspace" }
+ item_save.action = dalosp.menu.action_save
+ local item_import = iup.item { title = "Import Lua file" }
+ item_import.action = dalosp.menu.action_import
+ local item_reload = iup.item { title = "Reload all" }
+ item_reload.action = dalosp.menu.action_reload
+ local item_load_template = iup.item { title = "Load Template" }
+ item_load_template.action = dalosp.menu.action_load_template
local item_exit = iup.item { title = "Exit" }
item_exit.action = dalosp.menu.action_exit
local item_about = iup.item { title = "About" }
@@ -412,22 +745,62 @@ dalosp.menu = {
local east_menu = { radio = "1" }
local west_menu = { radio = "1" }
local south_menu = { radio = "1" }
- if type(dalos.objects) == "table" then
- local item
- for k, v in ipairs(dalos.objects) do
- item = iup.item { title = v.name }
- table.insert(add_menu, item)
- item = iup.item { title = v.name }
- table.insert(north_menu, item)
- item = iup.item { title = v.name }
- table.insert(east_menu, item)
- item = iup.item { title = v.name }
- table.insert(west_menu, item)
- item = iup.item { title = v.name }
- table.insert(south_menu, item)
+ local item
+ local add_submenus = { }
+ local north_submenus = { }
+ local east_submenus = { }
+ local west_submenus = { }
+ local south_submenus = { }
+ local category
+ local add_smenu, north_smenu, east_smenu, west_smenu, south_smenu
+ local categories = {}
+ for k, v in ipairs(dalos.objectstypes) do
+ category = v.category
+ if category then
+ if not add_submenus[category] then
+ add_submenus[category] = { }
+ north_submenus[category] = { }
+ south_submenus[category] = { }
+ east_submenus[category] = { }
+ west_submenus[category] = { }
+ table.insert(categories, 1, category)
+ end
+ add_smenu = add_submenus[category]
+ north_smenu = north_submenus[category]
+ east_smenu = east_submenus[category]
+ west_smenu = west_submenus[category]
+ south_smenu = south_submenus[category]
+ else
+ add_smenu = add_menu
+ north_smenu = north_menu
+ east_smenu = east_menu
+ west_smenu = west_menu
+ south_smenu = south_menu
end
+ item = iup.item { title = v.name }
+ item.action = function (self) dalosp.menu.add_object(canvas, v) end
+ table.insert(add_smenu, item)
+ item = iup.item { title = v.name }
+ item.action = function (self) dalosp.menu.set_cross(canvas, v, dalosp.NORTH) end
+ table.insert(north_smenu, item)
+ item = iup.item { title = v.name }
+ item.action = function (self) dalosp.menu.set_cross(canvas, v, dalosp.EAST) end
+ table.insert(east_smenu, item)
+ item = iup.item { title = v.name }
+ item.action = function (self) dalosp.menu.set_cross(canvas, v, dalosp.WEST) end
+ table.insert(west_smenu, item)
+ item = iup.item { title = v.name }
+ item.action = function (self) dalosp.menu.set_cross(canvas, v, dalosp.SOUTH) end
+ table.insert(south_smenu, item)
+ end
+ for i, v in ipairs(categories) do
+ table.insert(add_menu, 1, iup.submenu { iup.menu(add_submenus[v]), title = v })
+ table.insert(north_menu, 1, iup.submenu { iup.menu(north_submenus[v]), title = v })
+ table.insert(south_menu, 1, iup.submenu { iup.menu(south_submenus[v]), title = v })
+ table.insert(east_menu, 1, iup.submenu { iup.menu(east_submenus[v]), title = v })
+ table.insert(west_menu, 1, iup.submenu { iup.menu(west_submenus[v]), title = v })
end
- local menu_file = iup.submenu { iup.menu { item_exit }, title = "File" }
+ local menu_file = iup.submenu { iup.menu { item_new, item_load, item_save, iup.separator {}, item_import, item_reload, iup.separator {}, item_load_template, iup.separator {}, item_exit }, title = "File" }
local menu_add = iup.submenu { iup.menu(add_menu), title = "Add" }
local menu_cross = iup.submenu { iup.menu {
iup.submenu { iup.menu(north_menu), title = "North" },
@@ -447,7 +820,59 @@ dalosp.menu = {
}
dalosp.object = {
- default_draw = function (self, cv, x, y, w, h )
+ use_template = function (self, templates)
+ local ttpllst = {}
+ for n, v in pairs(templates) do
+ table.insert(ttpllst, n)
+ end
+ if #ttpllst == 0 then
+ local dlg = iup.messagedlg {
+ dialogtype = "Warning",
+ title = "No template",
+ value = "There's no template to use.\nPlease load templates from the main menu first.",
+ }
+ dlg:popup()
+ return iup.DEFAULT
+ end
+ table.sort(ttpllst)
+ local tpllst = "|"
+ for i, n in ipairs(ttpllst) do
+ tpllst = tpllst .. n .. "|"
+ end
+ local s, tind = iup.GetParam("Use Template", nil, "Template: %i" .. tpllst .. "\n", 0)
+ if not s then return iup.DEFAULT end
+ self:apply_template(templates[ttpllst[tind]])
+ end,
+
+ auto_template = function (self, templates, name)
+ for n, v in pairs(templates) do
+ if n == name then
+ self:apply_template(v)
+ end
+ end
+ end,
+
+ load_template = function (self)
+ local dlg = iup.filedlg {
+ dialogtype = "Open",
+ filter = "*.dtpl",
+ }
+ iup.Popup(dlg)
+ if (dlg.status + 0) == -1 then return end
+
+ local s, v = pcall(Input, dlg.value)
+ if not s then error("Problem loading file " .. dlg.value) end
+ local f = preload(v)
+ v:destroy()
+ if not f then error("Syntax error loading file " .. dlg.value) end
+ local t = f()
+ local data, otype, tname = t.data, t.otype, t.tname
+ if otype ~= self.ntype then error("Wrong template type: " .. otype) end
+
+ self:apply_template(data.template)
+ end,
+
+ default_draw = function (self, cv, x, y, w, h)
local x1, x2, y1, y2 = x, x + w, y, y + h
y1, y2 = cv:InvertYAxis(y2), cv:InvertYAxis(y1)
local cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
@@ -481,11 +906,13 @@ dalosp.object = {
end,
default_activate = function (self)
- print "activate"
+ print "default activate"
end,
default_configure = function (self)
- print "configure"
+ local s, n = iup.GetParam("Change name", nil, "Name: %s\n", self.name)
+
+ if s then self.name = n end
end,
change_curinput = function (self, delta)
@@ -524,10 +951,44 @@ dalosp.object = {
end
end,
+ default_get_settings = function (self)
+ return {}
+ end,
+
+ save_template = function (self, template)
+ if not template then template = self:gen_template() end
+ local dlg = iup.filedlg {
+ dialogtype = "Save",
+ filter = "*.dtpl",
+ }
+ iup.Popup(dlg)
+ if dlg.status == -1 then return end
+ local s, name, v
+ s, name = iup.GetParam("Export template", nil, "Template name: %s\n", "")
+ if not s then return end
+ s, v = pcall(Output, dlg.value)
+ if s then
+ v:write "---- Dalos template\nlocal "
+ dumpvars(v, dalos.version, "version")
+ v:write "if dalos.version.MAJOR < version.MAJOR or dalos.version.MAJOR == version.MAJOR and dalos.version.MINOR < version.MINOR then error 'Dalos version too old for this save.' end\n\nlocal "
+ dumpvars(v, template, "template")
+ v:write("return { data = template, otype = '" .. self.ntype .. "', tname = '" .. name .. "' }\n")
+ v:destroy()
+ else
+ error("Failed opening " .. dlg.value .. " for writing")
+ end
+ end,
+
create = function (dcanvas, tab, extra)
if not tab then tab = {} end
+ if not tab.name then
+ tab.name = tab.default_name
+ if tab.counter then
+ tab.name = tab.name .. " " .. tab.counter
+ end
+ end
local obj = {
- draw = dalosp.object.default_draw,
+ draw = tab.draw or dalosp.object.default_draw,
name = tab.name or "NoName",
color = tab.color or cd.GRAY,
ninputs = tab.ninputs or 0,
@@ -536,6 +997,7 @@ dalosp.object = {
outputs = {},
curinput = 1,
curoutput = 1,
+ ntype = tab.ntype,
quicksetting = tab.quicksetting,
otype = tab.otype or dalos.objtype.DUMMY,
activate = tab.activate or dalosp.object.default_activate,
@@ -548,8 +1010,15 @@ dalosp.object = {
input_change = tab.input_change or dalosp.object.default_inputchange,
output_change = tab.output_change or dalosp.object.default_outputchange,
set_houtput = dalosp.object.set_houtput,
+ get_settings = tab.get_settings or dalosp.object.default_get_settings,
houtputs = {},
get_linked_input = dalosp.object.get_linked_input,
+ save_template = dalosp.object.save_template,
+ load_template = dalosp.object.load_template,
+ use_template = dalosp.object.use_template,
+ auto_template = dalosp.object.auto_template,
+ apply_template = tab.apply_template,
+ gen_template = tab.gen_template,
dcanvas = dcanvas,
}
@@ -573,9 +1042,36 @@ dalosp.object = {
end,
}
+dalosp.status = {
+ create = function ()
+ local r
+
+ local s_square = iup.canvas { size = "10x", expand = "Vertical", border = "No", bgcolor = "0 255 0", }
+ local s_label = iup.label { expand = "Horizontal" }
+
+ r = iup.frame {
+ iup.hbox {
+ s_square,
+ iup.label { separator = "Vertical" },
+ s_label,
+ },
+ expand = "Horizontal",
+ }
+
+ r.square = s_square
+ r.label = s_label
+
+ dalos.active_status = r
+
+ return r
+ end,
+}
+
dalos.canvas = dalosp.canvas.create
dalos.menu = dalosp.menu.create
dalos.object = dalosp.object.create
+dalos.status = dalosp.status.create
+dalos.stypes = dalosp.canvas.stypes
dalos.objtype = {
UNKNOWN = 0,
@@ -587,172 +1083,41 @@ dalos.objtype = {
----------------
-dalosp.hexview = {
- activate = function (self)
- self.extra.hvdlg:show()
- end,
-
- input_change = function (self, ind)
- local extra = self.extra
- local hv = extra.hv
- local h = self:get_linked_input(ind)
- if not h then
- self.color = cd.YELLOW
- hv:updatehandle(nil)
- self.dcanvas:draw()
- return
- end
- if not h:canread() or not h:canseek() then
- self.color = cd.RED
- hv:updatehandle(nil)
- self.dcanvas:draw()
- return
- end
- self.color = cd.GREEN
- for i = 1, 12 do
- self:set_houtput(nil, i)
- self.oldcursors[i] = -1
- end
- hv:updatehandle(h)
- self.dcanvas:draw()
- end,
-
- configure = function (self)
- end,
-
- output_change = function (self, ind)
- self.watchees[ind] = self.outputs[ind] and true or false
- end,
-
- update_houtput = function (self, ind, cursor)
- local h = self:get_linked_input(1)
- if h and self.watchees[ind] then
- local obj = {
- h = h,
- hvo = self,
- ind = ind,
- origin = cursor,
- offset = 0,
- size = h:getsize() - cursor,
- canread = function (self) return true end,
- canwrite = function (self) return false end,
- canseek = function (self) return true end,
- canwatch = function (self) return self.h:canwatch() end,
- getname = function (self) return self.hvo.name .. ":" .. self.ind end,
- tell = function (self) return self.offset end,
- getsize = function (self) return self.size end,
- getmodif = function (self) return self.hvo:getmodif() end,
- flush = function (self) return self.hvo:flush() end,
- seek = function (self, offset, wheel)
- if wheel == SEEK_SET then
- self.offset = offset
- elseif wheel == SEEK_CUR then
- self.offset = self.offset + offset
- elseif wheel == SEEK_END then
- self.offset = self.size + offset
- else
- error "Unknown wheel"
- end
- self.h:seek(self.offset + self.origin)
- return self.offset
- end,
- read = function (self, userdata, count)
- count = math.min(count, self.size - self.offset)
-
- if count == 0 then
- if self.got_eof then self.lh:close() end
- self.got_eof = true
- return 0
- end
-
- self.got_eof = false
-
- local r = self.h:read(count, userdata)
- self.offset = self.offset + r
- if r == 0 then self.got_eof = true end
- return r
- end,
- }
- local newh = HandleLua(obj)
- obj.lh = newh
- self:set_houtput(newh, ind)
- end
- end,
-
- dalos_hv_cb = function (self, hv, reset)
- local m
- for i = 1, 10 do
- m = hv.markers[i]
- if self.oldcursors[i] ~= m then
- self:update_houtput(i, m)
- self.oldcursors[i] = m
- end
- end
-
- m = hv.kcursor
- if self.oldcursors[11] ~= m then
- self:update_houtput(11, m)
- self.oldcursors[11] = m
- end
-
- m = hv.mcursor
- if self.oldcursors[12] ~= m then
- self:update_houtput(12, m)
- self.oldcursors[12] = m
- end
- end,
-
- create = function (d, tab)
- if not tab.name then tab.name = "Hexview" end
- tab.otype = dalos.objtype.LUA_FILTER
- tab.activate = dalosp.hexview.activate
- tab.input_change = dalosp.hexview.input_change
- tab.output_change = dalosp.hexview.output_change
- tab.configure = dalosp.hexview.configure
- tab.ninputs = 1
- tab.noutputs = 12
-
- local hv = iupe.hexview { }
- local hvtb = iupe.hexview_toolbox { hexview = hv }
- local hvdlg = iup.dialog { iup.hbox { iup.frame { hv }, iup.sbox { direction = "WEST", hvtb } }, title = tab.name }
-
- local obj = dalos.object(d, tab, { hv = hv, hvtb = hvtb, hvdlg = hvdlg })
- obj.oldcursors = { }
- obj.watchees = { }
- obj.update_houtput = dalosp.hexview.update_houtput
- for i = 1, 12 do obj.oldcursors[i] = -1 end
-
- hv:registercb(dalosp.hexview.dalos_hv_cb, obj)
-
- return obj
- end,
-}
-
-dalos.hexview = dalosp.hexview.create
-dalos:register_obj("Hexview", dalos.hexview)
+load "dalos-luahandle.lua"
+load "dalos-hexview.lua"
+load "dalos-binaryops.lua"
+load "dalos-limiter.lua"
+load "dalos-textbuffer.lua"
+load "dalos-input.lua"
+load "dalos-tee.lua"
+load "dalos-buffer.lua"
+load "dalos-luafilter.lua"
+load "dalos-struct.lua"
+load "dalos-textview.lua"
+load "dalos-cd.lua"
+load "dalos-framebuffer.lua"
----------------
-d = dalos.canvas {}
-m = dalos.menu {}
-
-b1 = Buffer(true)
-b1:write("Buffer 1 contents")
-b2 = Buffer(true)
-b2:write("Buffer 2 contents")
+function dalos:main()
+ local d, m, s
+
+ d = self.canvas {}
+ m = self.menu(d)
+ s = self.status()
-o1 = dalos.object(d, { y = 30, x = 10, noutputs = 1, name = "Buffer 1", otype = dalos.objtype.HANDLE })
-o2 = dalos.object(d, { y = 120, x = 10, noutputs = 1, name = "Buffer 2", otype = dalos.objtype.HANDLE })
-h1 = dalos.hexview(d, { y = 60, x = 100, name = "Hexview 1" })
-h2 = dalos.hexview(d, { y = 60, x = 200, name = "Hexview 2" })
+ dlg = iup.dialog { iup.vbox { d, s }, title = "Dalos", menu = m, size = "400x250", shrink = "Yes", }
-o1:set_houtput(b1)
-o2:set_houtput(b2)
+ d.dialog = dlg
-dlg = iup.dialog { d, title = "Dalos", menu = m }
+ d:setstatus(dalos.stypes.INFO, "Dalos version " .. dalos.version.string .. " started")
+
+ local old_error = error
+ error = function(...) d:setstatus(dalos.stypes.ERROR, "Got a Lua error") old_error(...) end
-dalos.dialog = dlg
+ dlg:show()
+ iup.MainLoop()
+ dlg:hide()
+end
-dlg:show()
-iup.MainLoop()
-dlg:hide()
+if not archive_main then dalos:main() end
diff --git a/iupe-dbuffer.lua b/iupe-dbuffer.lua
index 4321206..8c1412f 100644
--- a/iupe-dbuffer.lua
+++ b/iupe-dbuffer.lua
@@ -4,6 +4,8 @@ loadmodule "lualibs"
if not iupep then iupep = {} end
+if not iupep.dbuffer then
+
iupep.dbuffer = {
map_cb = function (self)
self.cv = cd.CreateCanvas(cd.IUP, self)
@@ -41,3 +43,5 @@ iupep.dbuffer = {
return iup.DEFAULT
end,
}
+
+end
diff --git a/iupe-hexview.lua b/iupe-hexview.lua
index 0567cd0..a6817d9 100644
--- a/iupe-hexview.lua
+++ b/iupe-hexview.lua
@@ -34,6 +34,8 @@ markercolors = {
}
iupep.hexview = {
+ gridsize = { x = 8, y = 14 },
+
printgrid = function (self, msg, y, x)
local cvdb = self.cvdb
if not x then x = self.textcursor.x end
@@ -116,14 +118,24 @@ iupep.hexview = {
self:colorgrid(cursorcolors.GREEN, 2, kline, kcolumn * 3 + 10)
self:colorgrid(cursorcolors.GREEN, 1, kline, kcolumn + 12 + columns * 3)
- local marker
+ local marker, len, mlen
for i = 0, 10 do
- marker = self.markers[i]
- if marker ~= -1 then
+ marker = self.markers[i] or -1
+ marker = marker - filecursor
+ mlen = self.markerslengths[i]
+ if marker >= 0 and self.showmarkerslengths and mlen and mlen > 0 then
+ len = math.min(mlen, nbbytes - marker)
+ elseif marker >= 0 and marker < nbbytes then
+ len = 1
+ else
+ len = 0
+ end
+ for j = 1, len do
mline = math.floor(marker / columns)
mcolumn = marker % columns
self:colorgrid(markercolors[i], 2, mline, mcolumn * 3 + 10)
self:colorgrid(markercolors[i], 1, mline, mcolumn + 12 + columns * 3)
+ marker = marker + 1
end
end
@@ -340,6 +352,36 @@ iupep.hexview = {
elseif c == iup.K_m0 then
kaction = true
self.markers[10] = kcursor
+ elseif c == iup.K_c1 then
+ kaction = true
+ self.markers[1] = nil
+ elseif c == iup.K_c2 then
+ kaction = true
+ self.markers[2] = nil
+ elseif c == iup.K_c3 then
+ kaction = true
+ self.markers[3] = nil
+ elseif c == iup.K_c4 then
+ kaction = true
+ self.markers[4] = nil
+ elseif c == iup.K_c5 then
+ kaction = true
+ self.markers[5] = nil
+ elseif c == iup.K_c6 then
+ kaction = true
+ self.markers[6] = nil
+ elseif c == iup.K_c7 then
+ kaction = true
+ self.markers[7] = nil
+ elseif c == iup.K_c8 then
+ kaction = true
+ self.markers[8] = nil
+ elseif c == iup.K_c9 then
+ kaction = true
+ self.markers[9] = nil
+ elseif c == iup.K_c0 then
+ kaction = true
+ self.markers[10] = nil
elseif c == iup.K_SP then
kaction = true
end
@@ -491,7 +533,7 @@ iupep.hexview = {
end,
updategridsize = function (self, gridsize)
- self.gridsize = gridsize or { x = 8, y = 14 }
+ self.gridsize = gridsize or iupep.hexview.gridsize
self:resize_cb(self.width, self.height)
end,
@@ -509,7 +551,6 @@ iupep.hexview = {
tab.gridsize = nil
tab.cursor = "TEXT"
tab.expand = "Yes"
- tab.shrink = "Yes"
tab.border = "No"
tab.minsize = "0x0"
tab.size = "0x0"
@@ -544,9 +585,11 @@ iupep.hexview = {
r.filesize = handle and handle:getsize() or 0
r.mcursor = -1
r.markers = {}
- r.displaylines = -1
+ r.markerslengths = {}
+ r.showmarkerslengths = false
+ r.displaylines = 0
for i = 0, 10 do r.markers[i] = -1 end
- r.gridsize = gridsize or { x = 8, y = 14 }
+ r.gridsize = gridsize or iupep.hexview.gridsize
r.textcursor = { x = 0, y = 0 }
return r
end,