summaryrefslogtreecommitdiff
path: root/dalos.lua
diff options
context:
space:
mode:
Diffstat (limited to 'dalos.lua')
-rw-r--r--dalos.lua797
1 files changed, 581 insertions, 216 deletions
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