Skip to content

Instantly share code, notes, and snippets.

@reefwing
Created September 20, 2012 11:00
Show Gist options
  • Save reefwing/3755236 to your computer and use it in GitHub Desktop.
Save reefwing/3755236 to your computer and use it in GitHub Desktop.
Tutorial 17 - A Simple File Manager for Codea
-- Define Directory Types
ProjectInfo = 1
ProjectData = 2
LocalData = 3
GlobalData = 4
-- Class version
version = 1.1
-- Codea FileManager v1.1
--
-- A simple file manager to examine the Codea provided
-- persistent storage. Currently handles Local Data, Project Data,
-- Project Information and Global Data.
--
-- Reefwing Software
-- 15 September 2012
--
-- This class requires the ListScroll and TextItem class written by @sanit and
-- the MenuBar class written by @dave1707 (with some modifications).
--
-- WARNING - FILE DELETION CAN NOT BE UNDONE AND THE CLASS DOES NOT ASK FOR CONFIRMATION.
-- USE WITH EXTREME CAUTION AND BACK UP YOUR DATA BEFORE USING THIS
-- FILE MANAGER CLASS.
FileManager = class()
function FileManager:init()
-- Initialise the FileManager parameters and
-- load up the currently supported data stores.
directoryList = ListScroll(vec2(25, HEIGHT - 500), 200, 400)
directoryContents = {"Project Info", "Project Data", "Local Data", "Global Data"}
for i = 1, #directoryContents do
local item = TextItem(i, directoryContents[i])
if i == 1 then
-- pre select Project Info "Directory"
item.selected = true
end
directoryList:add(item)
end
currentDirectory = ProjectInfo
dataKeyList = ListScroll(vec2(227, HEIGHT - 500), 260, 400)
-- Pre-fetch results
infoKeyTable = {"Description", "Author", "Date", "Version", "Comments"}
loadProjectKeys()
loadLocalKeys()
loadGlobalKeys()
displayKeys(infoKeyTable)
currentKey = 1
valueString = readProjectInfo(infoKeyTable[currentKey])
-- Setup the MenuBar
MenuSetup()
end
-- Functions to read keys from the available pLists
function loadProjectKeys()
projectKeyTable = listProjectData()
if #projectKeyTable == 0 then
projectKeyTable = {"nil"}
end
end
function loadLocalKeys()
localKeyTable = listLocalData()
if #localKeyTable == 0 then
localKeyTable = {"nil"}
end
end
function loadGlobalKeys()
globalKeyTable = listGlobalData()
if #globalKeyTable == 0 then
globalKeyTable = {"nil"}
end
end
-- This function displays the keys passed in keyTable within the dataKeyList ListScroll
function displayKeys(keyTable)
dataKeyList.items = {}
for i = 1, #keyTable do
local item = TextItem(i, keyTable[i])
if i == 1 then
-- pre select first key in Project Info
item.selected = true
end
dataKeyList:add(item)
end
end
-- Setup the menu items at the top of the ListScrolls
-- Note that the call back functions are in the Main tab.
function MenuSetup()
pointer2 = nil
pointer3 = nil
b1tab = {}
b2tab = {}
local y = HEIGHT - 80
-- Create tables for main menu bar
table.insert(b1tab, MenuBar(80, y, 100, 30, "File", b2tab))
table.insert(b1tab, MenuBar(180, y, 100, 30, "Cancel", cancelFileManager))
table.insert(b1tab, MenuBar(280, y, 100, 30, "About", aboutFileManager))
pointer1 = b1tab
y = HEIGHT - 110
-- Create table for sub menu items
table.insert(b2tab, MenuBar(80, y, 100, 30, "Save", saveFile))
table.insert(b2tab, MenuBar(80, y - 30, 100, 30, "Load", loadFile))
table.insert(b2tab, MenuBar(80, y - 60, 100, 30, "Delete", deleteFile))
-- Global variables to prevent touches on scroll list
-- while subMenu is visible and to update the key list
-- if the directory changes.
subMenuShown = false
directoryChanged = false
end
-- Update functions for List Scrolls
function updateDirectorySelection()
local dlsi = directoryList.selectedItem
if dlsi ~= currentDirectory then
if dlsi == nil then
-- No Items Selected assign to default
dlsi = ProjectInfo
displayKeys(infoKeyTable)
elseif dlsi == ProjectData then
displayKeys(projectKeyTable)
elseif dlsi == ProjectInfo then
displayKeys(infoKeyTable)
elseif dlsi == LocalData then
displayKeys(localKeyTable)
elseif dlsi == GlobalData then
displayKeys(globalKeyTable)
end
currentDirectory = dlsi
directoryChanged = true
end
end
function updateKeySelection()
local dksi = dataKeyList.selectedItem
if dksi ~= currentKey or directoryChanged then
if directoryChanged then
dataKeyList.selectedItem = 1
currentKey = 1
directoryChanged = false
else
currentKey = dksi
end
if currentDirectory == nil then
-- No Directory Selected
valueString = ""
elseif currentDirectory == ProjectData and projectKeyTable[currentKey] ~= nil then
valueString = readProjectData(projectKeyTable[currentKey]) or "nil"
elseif currentDirectory == ProjectInfo and infoKeyTable[currentKey] ~= nil then
valueString = readProjectInfo(infoKeyTable[currentKey]) or "nil"
elseif currentDirectory == LocalData and localKeyTable[currentKey] ~= nil then
valueString = readLocalData(localKeyTable[currentKey]) or "nil"
elseif currentDirectory == GlobalData and globalKeyTable[currentKey] ~= nil then
valueString = readGlobalData(globalKeyTable[currentKey]) or "nil"
end
valueString = string.truncate(valueString, 150)
end
end
function FileManager:draw()
-- Codea does not automatically call this method
-- Handle Directory Selection
updateDirectorySelection()
updateKeySelection()
directoryList:draw()
dataKeyList:draw()
-- Draw Menu Bar
pushStyle()
fill(0,0,255,255)
rect(25, HEIGHT - 98, 725, 36)
popStyle()
MenuBar:menu1()
-- Draw the results window
pushStyle()
textWrapWidth(250)
textMode(CORNER)
font("Courier")
fontSize(24)
fill(255)
rect(489, HEIGHT - 500, 260, 400)
fill(0)
local _,h = textSize(valueString)
text(valueString, 496, HEIGHT - 100 - h)
popStyle()
end
function FileManager:touched(touch)
-- Codea does not automatically call this method
if touch.state == BEGAN then
MenuBar:check(touch)
end
if pointer2 ~= nil then
-- Sub menu visible
subMenuShown = true
elseif subMenuShown and touch.state == ENDED then
subMenuShown = false
else
-- Sub menu is not visible so handle scroll touches
directoryList:touched(touch)
dataKeyList:touched(touch)
end
end
-- String Helper
function string.truncate(str, num)
if string.len(str) > num then
str = string.sub(str,1,150) .. "..."
end
return str
end
-- FileManager
--
-- Codea FileManager v1.1
--
-- A simple file manager to examine the Codea provided
-- persistent storage. Currently handles Local Data, Project Data,
-- Project Information and Global Data.
--
-- This App demonstrates how to use this class in your project.
--
-- Reefwing Software
-- 15 September 2012
--
-- WARNING - FILE DELETION CAN NOT BE UNDONE AND DOES NOT ASK FOR CONFIRMATION.
-- USE WITH EXTREME CAUTION AND BACK UP YOUR DATA BEFORE USING THIS
-- FILE MANAGER CLASS.
supportedOrientations(ANY)
displayMode(FULLSCREEN)
-- Use this function to perform your initial setup
function setup()
-- Load test data to illustrate the FileManager class
-- First save some ProjectInfo data. This is specific to the App.
saveProjectInfo("Description", "File Manager for Codea v"..version)
saveProjectInfo("Author", "Reefwing Software")
saveProjectInfo("Date", "15 September, 2012")
saveProjectInfo("Version", version)
saveProjectInfo("Comments", "Original Release.")
print("-- Codea File Manager v"..version.."\n")
-- Save local data, this is accessible from within this App on your device.
saveLocalData("localDataKey", "Some local data. For example a high score.")
-- Save project data, this is accessible from within this App but isn't device specific.
saveProjectData("projectDataKey", "Some project data. For example level or map info.")
-- Save global data, this is accessible from any Codea App on this device.
saveGlobalData("globalDataKey", "Some global data. For example images from spritely or data from a level generator like dGenerator.")
-- Initialise the FileManager class
FileManager:init()
end
-- Menu Bar Call Back Methods
function cancelFileManager()
-- Custom implementation goes here
end
function aboutFileManager()
-- Custom implementation goes here
end
function saveFile()
-- Custom implementation goes here
end
function loadFile()
-- Custom implementation goes here
end
function deleteFile()
if currentDirectory == nil then
-- No Directory Selected
elseif currentDirectory == ProjectData and projectKeyTable[currentKey] ~= nil then
saveProjectData(projectKeyTable[currentKey], nil)
loadProjectKeys()
displayKeys(projectKeyTable)
currentKey = 1
valueString = string.truncate(readProjectData(projectKeyTable[currentKey]) or "nil",150)
elseif currentDirectory == ProjectInfo and infoKeyTable[currentKey] ~= nil then
-- delete is not currently supported for ProjectInfo because we can't
-- get a list of the keys in this pList.
elseif currentDirectory == LocalData and localKeyTable[currentKey] ~= nil then
saveLocalData(localKeyTable[currentKey], nil)
loadLocalKeys()
displayKeys(localKeyTable)
currentKey = 1
valueString = string.truncate(readLocalData(localKeyTable[currentKey]) or "nil",150)
elseif currentDirectory == GlobalData and globalKeyTable[currentKey] ~= nil then
saveGlobalData(globalKeyTable[currentKey], nil)
loadGlobalKeys()
displayKeys(globalKeyTable)
currentKey = 1
valueString = string.truncate(readGlobalData(globalKeyTable[currentKey]) or "nil",150)
end
end
-- View Handling
function orientationChanged(newOrientation)
-- Update ListScroll co-ordinates for new orientation
local y = HEIGHT - 500
if directoryList ~= nil then
directoryList.pos.y = y
end
if dataKeyList ~= nil then
dataKeyList.pos.y = y
end
-- Update Menu Bar co-ordinates for new orientation
y = HEIGHT - 80
if b1tab ~= nil then
for i = 1, #b1tab do
b1tab[i].y = y
end
end
y = HEIGHT - 110
if b2tab ~= nil then
for i = 1, #b2tab do
b2tab[i].y = y
y = y - 30
end
end
end
function draw()
-- This sets a black background color
background(0)
-- Draw the FileManager
FileManager:draw()
end
-- Touch Handler
function touched(touch)
-- Handle FileManager touches
FileManager:touched(touch)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment