I have two problems in this iup.lua program
they are described in the header comments and located in the code itself with 
all other pertinent information (search for ****). How can I resolve these 
issues by a generalized means?  I intend to 'objectivise' this program so that 
it can become a simple require to display simple tables. I will consider more 
complex tables once I am certain the iup functions are robust and correct.

thank you,
Ron Melby
--[[
Windows 10 64 Bit
Lua version 5.1
iup.lua version 3.11.2

functions:
 search for ****      <<<< explains the *PROBLEM*
            dbg = dbg <<<< set the breakpoint

_sfl_WRITE(_tbl)
takes an input table and writes it into the gridbox
  _set_IO
  determines whether a field is label or text
  _get_IO
  if a _usrdfn{buf} description is 'var' then call users program function cb_io

_set_ptr *PROBLEM*
sets row start handle and io fields handles

_sfl_CTL
vbox, hbox, buttons etc pack them up and display them

_sfl_READC *PROBLEM*
read and return changed records by handle

cb_io
callback program if _usrdfn['buf'][n] = 'var'
simple test function included in this program for testing.
in my program may need to pcall it to provide better error indications.

* ColeValleyGirl on FHUG.org.uk which uses lua and iup.lua for plugins
  explained a more rigorous callback function, but I did not understand it.

abbreviations:
sfl = subfile
ctl = control
fld = field
buf = buffer
readc = read changed records
var = variable
dsp = display
rtx = return table external
ptr = pointer (handle)

*TODO build similar program using matrix
      header under title.
      opt (handle) opt_01 etc tonumber(opt) changes meaning of readonly
      posn to
      _usrdfn  header

      expand to 'tree-d' subfile --nested table, two dependent tables? hbox and 
vbox combined? ie:
        will build like:
        Morris and Ruth Melby
          Morralee
          Ronalee
          Ronald
          Donald
          Richard
*TODO END

       two required args.
      1) table to display (for development using qsysval)
      2) a table that describes the fields to display
         and whether or not they are changeable
         ... the prototype is _usrdfn
 ]]

-- constants until require installed
local WS_Abort  = 'Abort'
local WS_CANCEL = false
local WS_Cancel = 'Cancel'
local WS_ENTER  = true
local WS_Ignore = 'Ignore'
local WS_OK     = 'OK'
local WS_Retry  = 'Retry'

local WS_ERR    = 2
local WS_YES    = 'Yes'
local WS_NO     = 'No'

local _usrdfn  = {} -- user instructions for subfile display
local fld_elem = 0  -- counter to perform checks at .new
local buf_elem = 0  -- counter to perform checks at .new
-- local atr_elem  = 0  -- counter to perform checks at .new

local rtx = {} -- return changed records via callback when I get readc working
local row = 0
local col = 0

-- using supplied instruction table _usrdfn ['fld'] and ['buf']
-- write subfile object
-- QSYSVAL table to write for testting
function _sfl_WRITE(_tbl)
  local hdl -- build handles for records, and io flds
  local __ptr = {} -- _cp = record handles, _dp = fld dta handles
  --[[
  __ptr[1] =
    {
   _cp =    { '_cp_01' == (handle) },  -- rcd nbr lookup handle, record 
handle(pointer)
   _dp[3] = { '_dp_03' == (handle) },  -- fld dta lookup handle, field 
handle(pointer)
   _dp[7] = { '_dp_07' == (handle) },  -- fld dta lookup handle, field 
handle(pointer)
   IO =
    },

  __ptr[2] =
    {
      _cp = { 'cp_02' == (handle) },  -- rcd lookup handle, record 
handle(pointer)
    - _dp = nil: does not exist for output only records.
    },

  ]]

  -- create a field io attribute if conditions are met to insert into subfile.
  function _set_IO(_OBJ)

    local _fldobj

    local function _get_IO()
      if (_OBJ._buf == 'KEY'
        or _OBJ._buf == 'o') then
        _OBJ._io = 'o'
        _OBJ.readonly ='YES'
        return
      end
      if _OBJ._buf == 'io' then
        _OBJ._io = 'io'
        _OBJ.readonly ='NO'
        return
      end

      if _OBJ._buf == 'var' then
        -- send key of file and fld  decide if it should be 'io' or 'o'
        -- 'u' for planned expansion
        local _buf = cb_io('u', _OBJ._key, _OBJ._fld)

        if _buf == 'io' then
          _OBJ.readonly ='NO'
          _OBJ._io = _buf
          return
        end

        if _buf == 'o' then
          _OBJ._io = _buf
          _OBJ.readonly ='YES'
          return
        end
        error("cb_io returned value that is not 'o' or 'io'.")
      end
    end -- fn _get_IO

    -- entry point
    _get_IO()
    if _OBJ._io == 'o' then
      _fldobj = iup.label(_OBJ)
      return _fldobj
    end
    if _OBJ._io == 'io' then
      _fldobj = iup.text(_OBJ)
      return _fldobj
    end
    error(string.format("_OBJ._io for %s is not 'o' or 'io'", _OBJ._fld))
  end

  function _set_ptr(matobj, row, col, _OBJ)

    -- data pointer subfile record number field and offset pointers
    if matobj == '_dp' then
      -- bld value handles
      if not (__ptr[row][matobj]) then
        __ptr[row][matobj] = {}
        __ptr[row][io] = {}
      end -- exists

      hdl = string.format('%s_%s_%s', matobj, row, col)
      iup.SetHandle(hdl, _OBJ)
      __ptr[row][matobj][col] = {hdl = hdl}

      --[[
      hdl = string.format('io_%s', row)
      dbg = dbg
      iup.SetHandle(hdl, _OBJ.title)
      **** bad argument #2 to 'SetHandle' (iup handle expected)
       __ptr[row][io] = {hdl = hdl}
     ]]

      return __ptr -- upvalue must return it
    end -- fld pointer

    -- space pointer subfile record number key pointers
    if matobj == '_cp' then
      if not (__ptr[row]) then
        __ptr[row] = {}
      end -- exists

      hdl = string.format('%s_%s', matobj, row)
      iup.SetHandle(hdl, _OBJ)
      __ptr[row][matobj] = {hdl = hdl}

      --[[ this will not work to set a pointer but it should see above
      if _usrdfn.opt then
        if not (__ptr[row][opt]) then
          __ptr[row][opt] = {}
        end
        hdl = string.format('opt_%s', row)
        iup.SetHandle(hdl, _OBJ.opt)
        __ptr[row][opt] = {hdl = hdl}
        return __ptr
      end
      ]]

      return __ptr  -- upvalue must return it
    end -- key pointer
  end -- rn _set_ptr

  local _sflobj =
  {
    numdiv         = fld_elem,      -- from count at .new
    expandchildren = 'HORIZONTAL',
    orientation    = 'HORIZONTAL',
    alignmentlin   = 'ACENTER',
    normalizesize  = 'YES',
    gaplin         = '8',
    gapcol         = '8',
    _ptr           = {}
  }

  local _sfl = iup.gridbox(_sflobj)

  for KEY, _ in pairs(_tbl) do -- _ = ARRAY
    -- start of key
    local this    = _tbl[KEY]
    local __val
    local _wsf    = _usrdfn['fld']  -- subfile field name
    local _wsb    = _usrdfn['buf']  -- io buffer attribute
    local _wsa    = _usrdfn['atr']  -- for expansion

    -- materialize unique hdl names
    local matobj

    -- start of fld by row
    row           = row + 1
    col           = 0               -- new row restart column count
    for s = 1, _sfl.numdiv do
      col = col + 1

      if s > 1 then              -- field get
        -- this.fld
        matobj = '_dp'
        _sflval  = this[_wsf[s]]
      else                       -- key get
        -- this.key
        matobj = '_cp'
        _sflval  = KEY           -- key always starts subfile line
      end

      local _OBJ =
      {
        title         =  _sflval,                         -- SFL DSP VALUE

        _key          =  KEY,                             -- KEY VALUE (from 
_tbl)
        _fld          = _wsf[s],                          -- FIELD NAME
        _fldval       = this[_wsf[s]],                    -- FIELD VALUE from 
_tbl
        _typ          = type(this[_wsf[s]] or _wsb[s]),   -- type(from _tbl)
        _buf          = _wsb[s],                          -- io from 
_usrdfn['buf']
        _io           = _wsb[s],                          -- o, io > 
crt_IO('var' > cb_io)
        _atr          = (_wsa[s] or 'rsv'),               -- unused(for 
expansion)
        readonly      = '',                               -- YES, NO > 
crt_IO('var' > cb_io)
        multiline     = 'NO',                             -- for now, one line.
      }

      _OBJ = _set_IO(_OBJ) -- create io display attributes
      -- need pointer?
      if matobj == '_cp'
      -- _ptr[row][matobj]
      or _OBJ._io == 'io' then
        -- _ptr[row][matobj][col] = {}
        __ptr = _set_ptr(matobj, row, col, _OBJ)
      end
      -- add the object
      _sfl:append(_OBJ)
    end -- sfl_flds
  end -- for _tbl

  _sfl._ptr = __ptr
  return _sfl
end

function _sfl_CTL(_sfldsp)
  local btn_atr = {}

  btn_atr =
  {
    title  = 'ENTER',
    action = function(self)
      _sfl_READC(_sfldsp) --error
      rtx.rc  = WS_ENTER
      return iup.CLOSE
    end
  }
  local btn_ENTER = iup.button(btn_atr)

  btn_atr =
  {
    title  = 'EXIT',
    action = function(self)
      rtx.rc  = WS_CANCEL
      rtx.TAG = ''
      return iup.CLOSE
    end
  }
  local btn_EXIT = iup.button(btn_atr)

  -- Creates vbox-scrollbox
  local _dsp = iup.vbox{iup.scrollbox{_sfldsp}}
  local fn_keys = iup.hbox{btn_ENTER, btn_EXIT}

  -- Creates a dialog with frame(s) and title
  local ws_dsp =
  {
    iup.vbox{_dsp, iup.hbox{fn_keys}},
    title  = 'System Values',
    size   = '180xHALF',
    margin = '8x8'
  }

  local _sfl = iup.dialog(ws_dsp)
  return _sfl
end -- fn _sfl_CTL

function _sfl_READC(_sfl)

  local _rcd =  _sfl._ptr
  local rtx  = {}

  -- local sfl_div   =  tonumber(_sfl.numdiv)  -- '3'
  -- local sfl_flds  =  tonumber(_sfl.numcol)  -- '3'
  -- local sfl_siz   =  tonumber(_sfl.numlin)  -- '10'

  -- for row, key in ipairs(_rcd) do
  for row = 1, _sfl.numlin do
    local _Kptr   = _rcd[row]._cp
    local _Fptr   = _rcd[row]._dp

    -- not being used at the moment
    local rcd     = iup.GetChild(_sfl, ((row - 1) * _sfl.numcol))

    --[[get return values here -- none of this works
    local _IOptr  = _rcd[row].io
    if _usrdfn[opt] then
    local _iohdl     = iup.GetHandle(_IOptr.hdl)
    local _ioval     = _io.title
    ]]

    if _Fptr then

      local _sflval, KEY, FLD, _fldval, _typ, _buf, _io, _atr, readonly, 
multiline
      for col, obj in pairs(_Fptr) do
        -- bld value handles

        local _OBJ   = iup.GetHandle(_Fptr[col].hdl)
        _sflval      = _OBJ.title         -- SFL DSP and Entry VALUE
        KEY          = _OBJ._key          -- KEY VALUE (from _tbl)
        FLD          = _OBJ._fld          -- FIELD NAME
        _fldval      = _OBJ._fldval       -- FIELD VALUE from _tbl
        _typ         = _OBJ._typ          -- type(from _tbl)
        _buf         = _OBJ._buf          -- io from _usrdfn['buf']
        _io          = _OBJ._io           -- o, io > crt_IO('var' > cb_io)
        _atr         = _OBJ._atr          -- unused(for expansion)
        readonly     = _OBJ.readonly      -- YES, NO > crt_IO('var' > cb_io)
        multiline    = _OBJ.multiline     -- for now, one line.

        dbg = dbg

        --[[
        **** inspect _OBJ.title, _sflval
        where is the returned value from iup?
        I expect it to be in the field title,
        which is what displays and what is entered in the field.
        how do I get the entries from the display?
        ]]
        if _sflval
        and _sflval ~= _fldval then
          rtx[#rtx + 1] = {KEY = KEY, FLD = FLD, OLDVAL = _fldval, NEWVAL = 
_sflval}
        end  -- chgrcd
        -- not being used at the moment
        local ctx = iup.GetBrother(iup.GetHandle(_Fptr[col].hdl))
      end -- all flds in row
    end --  fields  in the row
  end   -- records

  -- install callback for changed records
  -- cb_chgrcd{rtx)
end -- fn readc

-- this is for testing purposes and will be contained in the usr pgm as a 
callback
function cb_io(_u, key, fld)

  if QSYSVAL[key].QALWCHG == '1' then
    return 'io'
  end
  if QSYSVAL[key].QALWCHG == '0' then
    return 'o'
  end
end

QSYSVAL =
{
  ["QPRTFS"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = "",
    ["QDESC"] = "field separator",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = "",
  },
  ["QPRTPG"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = "",
    ["QDESC"] = "field paragraph",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = "",
  },
  ["QPRTLSC"] = {
    ["QCTX"] = "*SYS",
    ["QTYP"] = 0,
    ["QDESC"] = "Landscape PrintFile length",
    ["QALWCHG"] = "0",
    ["QRULES"] = {
    },
    ["QVAL"] = 198,
  },
  ["QBASLATI"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = 0,
    ["QDESC"] = "home base latitude",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = 46.4598781,
  },
  ["QAWBAS"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = "",
    ["QDESC"] = "Aboville length",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = "",
  },
  ["QPRTFD"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = "",
    ["QDESC"] = "field delimiter",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = "",
  },
  ["QGABAS"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = "",
    ["QDESC"] = "grave address length",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = "",
  },
  ["QBASLONG"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = 0,
    ["QDESC"] = "home base longitude",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = -95.660015,
  },
  ["QPRTPTT"] = {
    ["QCTX"] = "*SYS",
    ["QTYP"] = 0,
    ["QDESC"] = "Portrait PrintFile length",
    ["QALWCHG"] = "0",
    ["QRULES"] = {
    },
    ["QVAL"] = 198,
  },
  ["QFMBAS"] = {
    ["QCTX"] = "*USR",
    ["QTYP"] = "",
    ["QDESC"] = "Family Marriage length",
    ["QALWCHG"] = "1",
    ["QRULES"] = {
    },
    ["QVAL"] = "",
  },
}

_usrdfn =
{
  -- more to follow
  -- opt = (1 or 2 ' '),

  --[[ *REQUIRED ]]
  ['fld'] = {[1] = 'KEY', [2] = 'QCTX', [3] = 'QVAL',},
  ['buf'] = {[1] = 'KEY', [2] =    'o', [3] =  'var',},
  --[[ end *REQUIRED ]]
  -- ['atr'] = {}, -- for expansion after readc
}
for _,_ in ipairs(_usrdfn['fld']) do
  -- check for is %q etc
  fld_elem = fld_elem + 1
end
for _,_ in ipairs(_usrdfn['buf']) do
  -- check for {'KEY', 'o', 'io', 'var',}
  buf_elem = buf_elem + 1
end

--[[
for _,_ in ipairs(_usrdfn['atr']) do
  -- expansion
  atr_elem = atr_elem + 1
end
]]

if fld_elem ~= buf_elem then
  error(" ['fld'] and ['buf'] not equal.")
end

local _sflobj = _sfl_WRITE(QSYSVAL)
local ws_dsp = _sfl_CTL(_sflobj)
ws_dsp:show(iup.CENTER, iup.CENTER)
iup.MainLoop()
ws_dsp:destroy()

return
_______________________________________________
Iup-users mailing list
Iup-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/iup-users

Reply via email to