diff options
Diffstat (limited to 'dalos.lua')
-rw-r--r-- | dalos.lua | 797 |
1 files changed, 581 insertions, 216 deletions
@@ -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 |