stickynote enhanced to load/save data

load/save dialog as a part of system
This commit is contained in:
Alexander Weber 2017-12-16 12:54:49 +01:00
parent dab07b6783
commit 20819fc6ed
6 changed files with 242 additions and 29 deletions

21
API.md
View File

@ -43,6 +43,21 @@
- `mtos:set_theme(theme)`- Activate theme
- `mtos:save()` - Store all app-data to nodemeta. Called mostly internally so no explicit call necessary
- `mtos:pass_to_app(method, reshow, sender, ...)` - call custom "method" on app object. Used internally. Reshow means update formspec after update
- `mtos:select_file_dialog(param)` - call the select file dialog ('os:select_file')
```
if fields.load then
mtos:select_file_dialog({
mode = 'open', -- open/select or save mode
allowed_disks = {'hdd', 'removable'}, -- disks shown in disk overview ('ram', 'hdd', 'removable', 'cloud' or 'system')
selected_disk_name = data.selected_disk_name, -- Start selection on disk
selected_file_name = data.selected_file_name, -- Start selection with file
store_name = store_area, -- The storage_name used for fliles (Sample 'stickynote:files')
prefix = 'open_', -- Prefix for return files
})
elseif fields.open_selected_disk and fields.open_selected_file then
data.selected_disk_name = fields.open_selected_disk -- Selected disk (prefix 'open_' is used)
data.selected_file_name = fields.open_selected_file -- Selected file (prefix 'open_' is used)
```
### Operating system attributes
`mtos.pos` - Computers position vector
@ -77,7 +92,7 @@ same as register_app, but the view flag is set. app_name and app_icon not necess
### App Object
`local app = mtos:get_app(appname)` - Give the app object internal_shortname, connected to given mtos. Not necessary in formspec_func or receive_fields_func because given trough interface
- `app:back_app()` - Go back to previous app/view
- `app:back_app(fields, sender)` - Go back to previous app/view. Trough fields/sender additional data can be sent to the previous app trough receive_fields_func
- `app:exit_app()` - Delete call stack and return to launcher
@ -110,12 +125,12 @@ Can be used for non-data and/or system tasks. For usual data store please use th
- `bdev:get_ram_disk()` ram store - a table with all app-related storage partitions
- `bdev:get_hard_disk()` hdd store - a table with all app-related storage partitions, if hard disk capatibility exists
- `bdev:get_removable_disk()` removable data object (drive)
- `bdev:get_cloud_disk(store_name)` - Get named cloud storage
- `bdev:get_cloud_disk(storage_name)` - Get named cloud storage
- `bdev:sync()` - Write/store all opened and maybe changed data
### Storage methods
- `get_boot_disk()` - Check which device can be booted. possible return value is "hdd" or "removable"
- `get_app_storage(disk_type, store_name)` - Get data storage table to be used in apps.
- `get_app_storage(disk_type, storage_name)` - Get data storage table to be used in apps.
- disk_type can be 'ram', 'hdd', 'removable', 'cloud' or 'system'. System is eather hdd or removable storage depending on booted device
- store_name is usually the app name. 'os' is reserved for System related saves

View File

@ -48,8 +48,11 @@ function app_class:receive_data(method, reshow, sender, ...)
end
-- Back to previous app in stack
function app_class:back_app()
function app_class:back_app(fields, sender)
self.os.sysram.current_app = self.os:appstack_pop()
if fields then
self.os:pass_to_app('receive_fields_func', true, sender, fields)
end
self.os:set_app(self.os.sysram.current_app)
end

160
apps/os_dialogs_app.lua Normal file
View File

@ -0,0 +1,160 @@
-- Tool to get data
local function get_file(key, value)
if not value then
return { name = key }
elseif type(value) == 'string' then
return { name = key, content = value }
else
return {
name = key,
-- content = value.content or value,
owner = value.owner,
ctime = value.ctime,
}
end
end
laptop.register_view('os:select_file', {
formspec_func = function(app, mtos)
local param = mtos.bdev:get_app_storage('ram', 'os:select_file').param
local allowed_disks = param.allowed_disks or { 'system' }
local selected_disk
if param.selected_disk_name then
selected_disk = mtos.bdev:get_app_storage(param.selected_disk_name, param.store_name)
end
-- Get all available storage and check the storage_list
local storage_list = {}
for idx, disk in ipairs(allowed_disks) do
local dev_exists = mtos.bdev:get_app_storage(disk, param.store_name)
if dev_exists then
if not selected_disk then
selected_disk = dev_exists
param.selected_disk_name = disk
end
table.insert(storage_list, disk)
end
end
-- Get sorted files list
param.files_list = {}
if selected_disk then
for key, value in pairs(selected_disk) do
table.insert(param.files_list, get_file(key, value))
end
end
table.sort(param.files_list, function(a,b) return a.name<b.name end)
-- adjust tilte
if param.mode == 'save' then
param.message = 'Save file as'
param.button_txt = 'Save'
elseif param.mode == 'open' then
param.message = 'Open file'
param.button_txt = 'Open'
else
param.message = 'select file'
param.button_txt = 'Select'
end
app.app_info = param.message
-- available devices
local formspec = "background[0,1.5;1.4,6;"..mtos.theme.contrast_bg.."]"
for idx, store in ipairs(storage_list) do
local icon_pos = '0.2,'..(idx+0.8)
if store == param.selected_disk_name then
formspec = formspec .. 'background['..icon_pos..';1,1;'..mtos.theme.minor_button..']'
end
if store == 'removable' then
formspec = formspec .. 'item_image_button['..icon_pos..';1,1;'.. mtos.bdev:get_removable_disk().def.name..';disksel_removable;]'
elseif store == 'hdd' then
formspec = formspec .. 'item_image_button['..icon_pos..';1,1;'.. mtos.hwdef.nodename..';disksel_hdd;]'
else
formspec = formspec .. mtos.theme:get_button(icon_pos..';1,1', 'minor', 'disksel_'..store, store)
end
end
formspec = formspec .. mtos.theme:get_button('0,7.7;1.4,1', 'minor', 'mount', 'Mount')
-- Files table
formspec = formspec .. "tablecolumns[" ..
"text;".. -- subject
"text,padding=1.5;".. -- owner
"text,padding=1.5,align=right]".. -- date
"table[1.5,1.5;10.8,7.1;filesel;"
local selected_idx = ""
for idx, file in ipairs(param.files_list) do
if idx > 1 then
formspec = formspec..','
end
formspec = formspec..file.name..','..(file.owner or '')..','
if file.ctime then
formspec = formspec..os.date("%c", file.ctime)
end
if file.name == param.selected_file_name then
selected_idx = idx
end
end
formspec = formspec .. ";"..selected_idx.."]"
-- Buttons
if param.mode == 'save' then
formspec = formspec .. "background[1.5,8.8;11,1.2;"..mtos.theme.contrast_bg.."]" ..
'label[1.6,9.1;File name:]'.."field[3.2,9.3;5.5,0.8;filename;;"..(param.selected_file_name or "").."]"
else
formspec = formspec .. mtos.theme:get_label('1.5, 9.3', "Selected file: "..(param.selected_file_name or ""))
end
if param.selected_file_name and param.selected_file_name ~= "" and
selected_disk and selected_disk[param.selected_file_name] then
formspec = formspec .. mtos.theme:get_button('10.2,8.9;1.5,1', 'minor', 'delete', 'Delete')
formspec = formspec .. mtos.theme:get_button('8.5,8.9;1.5,1', 'major', 'select', param.button_txt)
elseif param.mode == 'save' then
formspec = formspec .. mtos.theme:get_button('8.5,8.9;1.5,1', 'major', 'select', param.button_txt)
:select_file_dialog(param) end
return formspec
end,
-- Input processing
receive_fields_func = function(app, mtos, sender, fields)
local st = mtos.bdev:get_app_storage('ram', 'os:select_file')
local param = st.param
if fields.filename then
param.selected_file_name = fields.filename
end
for field, value in pairs(fields) do
if field:sub(1,7) == 'disksel' then
param.selected_disk_name = field:sub(9,-1)
break
end
end
if fields.mount then
mtos:set_app("removable")
elseif fields.filesel then
local event = minetest.explode_table_event(fields.filesel)
if param.files_list[event.row] then
param.selected_file_name = param.files_list[event.row].name
end
elseif fields.select and param.selected_file_name and param.selected_file_name ~= ""
and param.selected_disk_name and param.selected_disk_name ~= "" then
param.prefix = param.prefix or ""
local pass_fields = {
[param.prefix..'selected_disk'] = param.selected_disk_name,
[param.prefix..'selected_file'] = param.selected_file_name,
}
app:back_app(pass_fields, sender)
st.param = nil
elseif fields.delete and param.selected_disk_name and param.selected_file_name then
local store = mtos.bdev:get_app_storage(param.selected_disk_name, param.store_name)
if store then
store[param.selected_file_name] = nil
end
end
end
})

View File

@ -1,16 +1,18 @@
local store_area = 'stickynote:files'
laptop.register_app("stickynote", {
app_name = "Notepad",
app_icon = "laptop_notes_pad.png",
app_info = "Write notes in a text document.",
app_info = "Write notes in a text document",
formspec_func = function(app, mtos)
local data = mtos.bdev:get_app_storage('system', 'stickynote')
data.files = data.files or {}
if data.selected_file then
data.text = data.files[data.selected_file]
end
data.text = data.text or ""
if data.selected_disk_name and data.selected_file_name then
app.app_info = app.app_info..' - Open File: '..data.selected_disk_name..' / '..data.selected_file_name
end
-- cache sorted files list
if not data.fileslist_sorted then
data.fileslist_sorted = {}
@ -20,31 +22,55 @@ laptop.register_app("stickynote", {
table.sort(data.fileslist_sorted)
end
local formspec = "background[0,0.35;15.2,8.2;"..mtos.theme.contrast_bg.."]"..
"textarea[0.35,0.35;15.08,9.5;text;;"..minetest.formspec_escape(data.text).."]"..
"dropdown[0,9;4,1;file_sel;"
local selected_idx
for idx, filename in ipairs(data.fileslist_sorted) do
if idx > 1 then
formspec = formspec..','
end
formspec = formspec .. filename
if data.selected_file and data.selected_file == filename then
selected_idx = idx
end
end
formspec = formspec .. ";"..(selected_idx or "").."]"..
mtos.theme:get_button('4,9;1.5,0.8', 'minor', 'load', 'Load', 'Load file')..
mtos.theme:get_button('5.7,9;1.5,0.8', 'minor', 'delete', 'Delete', 'Delete file')..
"field[7.6,9.3;4,0.8;filename;;"..(data.selected_file or "").."]"..
mtos.theme:get_button('11.6,9;1.5,0.8', 'minor', 'save', 'Save', 'Save file')
local formspec = "background[0,1.35;15.2,8.35;"..mtos.theme.contrast_bg.."]"..
"textarea[0.35,1.35;15.08,9.5;text;;"..minetest.formspec_escape(data.text).."]"..
mtos.theme:get_button('0,0.5;1.5,0.8', 'minor', 'clear', 'New', 'New file')..
mtos.theme:get_button('2,0.5;1.5,0.8', 'minor', 'load', 'Load', 'Load file')..
mtos.theme:get_button('4,0.5;1.5,0.8', 'minor', 'save', 'Save', 'Save file')
return formspec
end,
receive_fields_func = function(app, mtos, sender, fields)
local data = mtos.bdev:get_app_storage('system', 'stickynote')
if fields.text then
local data = mtos.bdev:get_app_storage('system', 'stickynote')
data.text = fields.text
end
if fields.load then
mtos:select_file_dialog({
mode = 'open',
allowed_disks = {'hdd', 'removable'},
selected_disk_name = data.selected_disk_name,
selected_file_name = data.selected_file_name,
store_name = store_area,
prefix = 'open_',
})
elseif fields.open_selected_disk and fields.open_selected_file then
data.selected_disk_name = fields.open_selected_disk
data.selected_file_name = fields.open_selected_file
local store = mtos.bdev:get_app_storage(data.selected_disk_name, store_area)
if store then
data.text = store[data.selected_file_name].content
end
elseif fields.save then
mtos:select_file_dialog({
mode = 'save',
allowed_disks = {'hdd', 'removable'},
selected_disk_name = data.selected_disk_name,
selected_file_name = data.selected_file_name,
store_name = store_area,
prefix = 'save_',
})
elseif fields.save_selected_disk and fields.save_selected_file then
data.selected_disk_name = fields.save_selected_disk
data.selected_file_name = fields.save_selected_file
local store = mtos.bdev:get_app_storage(data.selected_disk_name, store_area)
if store then
store[data.selected_file_name] = { content = data.text, ctime = os.time(), owner = sender:get_player_name() }
end
elseif fields.clear then
data.selected_disk_name = nil
data.selected_file_name = nil
data.text = ""
end
end
})

View File

@ -167,6 +167,8 @@ function laptop.register_hardware(name, hwdef)
-- set node configuration for hooks
local merged_hwdef = table.copy(hwdef)
merged_hwdef.name = name
merged_hwdef.nodename = nodename
for k,v in pairs(hwdef.node_defs[variant]) do
merged_hwdef[k] = v
end

7
os.lua
View File

@ -141,6 +141,13 @@ function os_class:save()
self.bdev:sync()
end
-- Use parameter and launch the select_file dialog
-- Return values will be send as fields to the called app
function os_class:select_file_dialog(param)
local store = self.bdev:get_app_storage('ram', 'os:select_file')
store.param = param
self:set_app('os:select_file')
end
-----------------------------------------------------
-- Get Operating system object
-----------------------------------------------------