Last Modified: 2023-09-23

TODO

editor/controller/save.lua
editor/parts/controller/properties/save.lua

implementation Details

the following functions in editor.controller.index class are mainly used for CRUD of json/lua files in select, save, delete etc. See editor.controller.save.

separate controllers for the audio, group, timer and variable components are implemented i.e

### select (read)

See editor.parts.controller directory. selectXXX lua reads json and displays a UI table. The data is passed by nanostore such as bookStore:set, pageStore:set.

nanostore is used as an experimental usage

  1. selectApp.lua

    local appFolder = params.appFolder or system.pathForFile( "App", system.ResourceDirectory )
    
    if params.useTinyfiledialogs then
      appFolder = tfd.selectFolderDialog({
        title = "select App folder",
        default_path = path
      })
      -- print("", appFolder)
    end
    
    if success then
      local books = {}
      for file in lfs.dir( appFolder ) do
        if util.isDir(file) then
          -- print("",  "Found file: " .. file )
          -- set them to nanostores
          if file:len() > 3 and file ~="kwikEditor" then
            table.insert(books, {name = file, path= util.PATH(appFolder.."/"..file)})
          end
        end
      end
      if #books > 0 then
        UI.editor.bookStore:set(books)
      end
    
  2. selectBook.lua

    local path =system.pathForFile( "App/"..bookName.."/models", system.ResourceDirectory)
    UI.editor.currentBook = bookName
    local success = lfs.chdir( path ) -- isDir works with current dir
    if success then
      local pages = {}
      for file in lfs.dir( path ) do
        if util.isDir(file) then
          -- set them to nanostores
          if file:len() > 3 and file ~='assets' then
            table.insert(pages, {name = file, path= util.PATH(path.."/"..file)})
          end
        end
      end
      if #pages > 0 then
        UI.editor.pageStore:set(pages)
      end
    end
    
  3. selectPage.lua

    if params.page:len() > 0 and UI.page ~= params.page then
      local app = App.get()
      app:showView("components." .. params.page .. ".index", {effect = "slideDown"})
    end
    


create a new component from toolbar


UI.scene.model

UI.scene.model is set when selectPage is called

local scene = require('controller.scene').new(sceneName, {
name = "page1",
components = {
  layers = {
        {  bg={
                          } },
        {  gotoBtn={ --class={"animation"}
                          } },
        {  title={ class={"linear"} } },
  },
  audios = {},
  groups = {},
  timers = {},
  variables = {},
  page = { }
},
commands = { "eventOne", "eventTwo", "act01" },
onInit = function(scene) print("onInit") end
})

util.read() function parses “App/”..book.."/models/"..page .."/index.json"

...
ret.layers = parser(decoded)
...
setFiles(ret.audios, "/audios/short")
setFiles(ret.audios, "/audios/long")
setFiles(ret.groups, "/groups")
setFiles(ret.commands, "/commands")
return ret
{
  layers = {
    {name = "layerOne", parent="", children = {
        {name="childOne}, parent="layerOne", children = {}}
      }
    },
    {name = "layerTwo", parent="", children = {}},
  },
  audios = {}
}

save (write)

CRUD operations on json/lua files are mainly for commands and components in a selected page

the editor does not support to create a new entry of App, Book, Page. The properties can be modified for App, Book, Page.

layer names must be unique in a scene model.

```lua
util.createIndexModel(UI.scene.model, UI.editor.currentLayer, classname)
```

```lua
scene = {
  name = "canvas",
  components = {
    layers = {
        {  back={
                          } },
        {  butBlue={ class={"button"}, {A={}}, {B={}}
                          } },
        {  butWhite={
                          } },
    },
    audios = {  },
    groups = {  },
    timers = {  },
    variables = {  },
    others = {  }
  },
}
```
- render App.booxX.components.pageX.index.lua
- save json
local name = ...
local parent, root = parent_root(name)
local util = require("editor.util")
local json = require("json")
--
-- save command performs on one entry.
-- If user switch to another entry without saving, the previous change will be lost.
--
local instance =
  require("commands.kwik.baseCommand").new(
  function(params)
    local UI = params.UI
    local props = params.props
    local tool = UI.editor:getTool(props.class) -- each tool.contoller can overide render/save. So page tools of audio, group, timer should use own render/save
    if tool then
      local files = {}
      local toolName = UI.editor:getToolName(props.class)
      local filename = props.name
      local classname = props.class:lower()
      -------------
      -- save lua
      files[#files+1] = tool.controller:render(UI.editor.currentBook, UI.page, UI.editor.currentLayer, toolName, classname, props)
      -----------
      --- save json
      local decoded = params.decoded or {}
      decoded[props.index] = props
      --
      files[#files+1] = tool.controller:save(UI.editor.currentBook, UI.page, UI.editor.currentLayer,toolName, decoded)
      -----------
      --- Update components/pageX/index.lua model/pageX/index.json
      local updatedModel = util.createIndexModel(UI.scene.model, UI.editor.currentLayer, classname)
      files[#files+1] = tool.controller:renderIndex(UI.editor.currentBook, UI.page, updatedModel)
      files[#files+1] = tool.controller:saveIndex(UI.editor.currentBook, UI.page, UI.editor.currentLayer,classname, updatedModel)
      ----------
      -- publish
      util.executePubish(files)
    else
      print("tool not found for", props.class)
    end
  end
)
--
return instance

assets

media files of audio, layer replacements(video, spritesheet, particle, syncText, web) in App/bookX/assets folder are indexed with linked layers in assets.json

So tool.controller:save() also performs a write operation on assets.json