diff options
-rw-r--r-- | dalos-struct.lua | 221 | ||||
-rw-r--r-- | dalos.lua | 2 |
2 files changed, 204 insertions, 19 deletions
diff --git a/dalos-struct.lua b/dalos-struct.lua index 350e329..7d6b8b0 100644 --- a/dalos-struct.lua +++ b/dalos-struct.lua @@ -24,8 +24,27 @@ dalosp.struct = { "uint64",
"float",
"double",
- "asciiz",
"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)
@@ -42,6 +61,96 @@ dalosp.struct = { input_change = function (self)
end,
+ offset = function (self, lin)
+ local cache = self.extra.cache
+ return cache[lin]
+ 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
+ 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 = "All"
+ 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 = "All"
+ 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)
@@ -49,10 +158,10 @@ dalosp.struct = { 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 then
+ 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 then
+ 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
@@ -62,6 +171,17 @@ dalosp.struct = { 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)
+ end
end,
cfg_value_cb = function (self, lin, col)
@@ -73,22 +193,50 @@ dalosp.struct = { elseif col == 7 then
return "Size"
elseif col == 8 then
- return "CumSize"
+ return "Enum"
+ elseif col == 9 then
+ return "Value Check"
+ elseif col == 10 then
+ return "Offset"
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
+ return self.struct:offset(lin)
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
+ 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 = nnewval
+ self.struct:cacheoffset()
+ elseif col == 8 then
+ -- enum
+ elseif col == 9 then
+ -- value check
+ end
end,
- insert_line = function (self)
- local mx = self.cfg_dlg.mx
- mx.numlin = mx.numlin + 1
- mx.numlin_visible = mx.numlin_visible + 1
- end,
-
cfg_dropcheck_cb = function (self, lin, col)
return col == 6 and iup.DEFAULT or iup.IGNORE
end,
@@ -97,6 +245,18 @@ dalosp.struct = { if mode == 1 then
return (col >= 5 and col <= 7) and iup.DEFAULT or iup.IGNORE
else
+ if update == 0 then return iup.DEFAULT end
+ if col == 5 then
+ -- lookup duplicates in names
+ elseif col == 6 then
+ -- do a check on the dropdown ? I don't think so
+ elseif col == 7 then
+ -- do a check on the size; can be the name of another field
+ elseif col == 8 then
+ -- enum
+ elseif col == 9 then
+ -- value check
+ end
return iup.DEFAULT
end
end,
@@ -108,13 +268,14 @@ dalosp.struct = { drop[i] = v
end
drop.value = self.previousvalue
+ drop.visible_items = 15
return iup.DEFAULT
end,
create = function (d, tab, settings)
tab.ninputs = 1
- tab.noutputs = 0
+ tab.noutputs = 1
tab.otype = dalos.objtype.LUA_VIEWER
tab.configure = dalosp.struct.configure
tab.activate = dalosp.struct.activate
@@ -128,23 +289,35 @@ dalosp.struct = { local extra = { }
if not settings then settings = {} end
+ extra.entries = settings.entries or {}
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:cacheoffset()
local cmx = iup.matrix {
- numcol = 8,
- numcol_visible = 8,
+ numcol = 10,
+ numcol_visible = 10,
usetitlesize = "Yes",
rasterwidth1 = 12,
rasterwidth2 = 12,
rasterwidth3 = 12,
rasterwidth4 = 12,
- rasterwidth5 = 150,
+ rasterwidth5 = 120,
rasterwidth6 = 80,
rasterwidth7 = 80,
rasterwidth8 = 80,
+ rasterwidth9 = 120,
+ rasterwidth10 = 40,
resizematrix = "Yes",
readonly = "No",
draw_cb = dalosp.struct.cfg_draw_cb,
@@ -156,10 +329,22 @@ dalosp.struct = { click_cb = dalosp.struct.cfg_click_cb,
struct = obj,
}
- local amx = iup.matrix {}
+ local amx = iup.matrix {
+ numcol = 2,
+ numcol_visible = 2,
+ usetitlesize = "Yes",
+ rasterwidth1 = 120,
+ rasterwidth2 = 120,
+ struct = obj,
+ }
+ 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 {},
@@ -171,11 +356,11 @@ dalosp.struct = { },
},
- size = "350x120",
+ size = "450x220",
+ mx = cmx,
+ lsize = lsize
}
- obj.cfg_dlg.mx = cmx
-
obj.actv_dlg = iup.dialog {
amx,
}
@@ -816,7 +816,7 @@ dalosp.menu = { } dalosp.object = { - default_draw = function (self, cv, x, y, w, h ) + 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 |