- split it into github/easysoft/zentaomobile.
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 17 KiB |
@@ -1,103 +0,0 @@
|
||||
|
||||
local storyboard = require( "storyboard" )
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
loginAPI = ""
|
||||
sessionAPI = ""
|
||||
myTodoAPI = ""
|
||||
myBugAPI = ""
|
||||
myTaskAPI = ""
|
||||
|
||||
config = {}
|
||||
session = {}
|
||||
|
||||
function autoLogin()
|
||||
local response = {}
|
||||
-- 获取config
|
||||
local result = http.request {url = configAPI, method = "GET", sink = ltn12.sink.table(response) }
|
||||
|
||||
if table.getn(response) == 0 then
|
||||
native.showAlert("提示", "网络错误,请查看网络或重新设置!", {"我知道了"} )
|
||||
else
|
||||
for i, val in pairs(response) do
|
||||
config = json.decode(val)
|
||||
end
|
||||
|
||||
-- 设置API地址
|
||||
if config.requestType == "GET" then
|
||||
loginAPI = zentaoRoot .. "?m=user&f=login"
|
||||
sessionAPI = zentaoRoot .. "?m=api&f=getSessionID&t=json"
|
||||
|
||||
myTodoAPI = zentaoRoot .. "?m=my&f=todo&t=json"
|
||||
myTaskAPI = zentaoRoot .. "?m=my&f=task&t=json"
|
||||
myBugAPI = zentaoRoot .. "?m=my&f=bug&t=json"
|
||||
elseif config.requestType == "PATH_INFO" then
|
||||
loginAPI = zentaoRoot .. "user-login.json?a=1"
|
||||
sessionAPI = zentaoRoot .. "api-getsessionid.json?a=1"
|
||||
|
||||
myTodoAPI = zentaoRoot .. "my-todo.json?a=1"
|
||||
myTaskAPI = zentaoRoot .. "my-task.json?a=1"
|
||||
myBugAPI = zentaoRoot .. "my-bug.json?a=1"
|
||||
end
|
||||
|
||||
-- 获取session
|
||||
http.request{url = sessionAPI, method = "GET", sink = ltn12.sink.table(session)}
|
||||
|
||||
if table.getn(session) == 0 then
|
||||
native.showAlert("提示", "网络错误,请查看网络或重新设置!", {"我知道了"} )
|
||||
else
|
||||
session = json.decode(table.concat(session))
|
||||
session.data = json.decode(session.data)
|
||||
|
||||
-- 用户登录
|
||||
local response2 = {}
|
||||
|
||||
mixPassword = crypto.digest(crypto.md5, md5Password .. session.data.rand)
|
||||
loginAPI = loginAPI .. "&account=" .. account .. "&password=" .. mixPassword .. "&" .. session.data.sessionName .. "=" .. session.data.sessionID
|
||||
http.request{url = loginAPI, method = "GET", sink = ltn12.sink.table(response2) }
|
||||
|
||||
if json.decode(table.concat(response2)).status == "failed" then
|
||||
native.showAlert("登录失败", "网络问题,或用户信息设置错误!", {"我知道了"})
|
||||
else
|
||||
storyboard.gotoScene(true, "index", "slideLeft", 100)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Called when the scene's view does not exist:
|
||||
function scene:createScene( event )
|
||||
local screenGroup = self.view
|
||||
|
||||
zentaoImg = display.newImage("zentao.png")
|
||||
zentaoImg.xOrigin = display.contentWidth/2
|
||||
zentaoImg.yOrigin = display.contentHeight/2
|
||||
screenGroup:insert(zentaoImg)
|
||||
|
||||
end
|
||||
|
||||
-- Called immediately after scene has moved onscreen:
|
||||
function scene:enterScene( event )
|
||||
timer.performWithDelay(2000, autoLogin)
|
||||
end
|
||||
|
||||
-- Called when scene is about to move offscreen:
|
||||
function scene:exitScene( event )
|
||||
local group = self.view
|
||||
end
|
||||
|
||||
-- Called prior to the removal of scene's "view" (display group)
|
||||
function scene:destroyScene( event )
|
||||
local group = self.view
|
||||
end
|
||||
|
||||
scene:addEventListener( "createScene", scene )
|
||||
scene:addEventListener( "enterScene", scene )
|
||||
scene:addEventListener( "exitScene", scene )
|
||||
scene:addEventListener( "destroyScene", scene )
|
||||
|
||||
return scene
|
||||
|
||||
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -1,15 +0,0 @@
|
||||
settings =
|
||||
{
|
||||
iphone =
|
||||
{
|
||||
plist =
|
||||
{
|
||||
CFBundleIconFile = "Icon.png",
|
||||
CFBundleIconFiles = {
|
||||
"Icon.png",
|
||||
"Icon@2x.png",
|
||||
"Icon-72.png",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1,12 +0,0 @@
|
||||
-- config.lua
|
||||
|
||||
application =
|
||||
{
|
||||
content =
|
||||
{
|
||||
width = 320,
|
||||
height = 480,
|
||||
scale = "letterbox"
|
||||
|
||||
},
|
||||
}
|
||||
@@ -1,806 +0,0 @@
|
||||
--[==[
|
||||
|
||||
David Kolf's JSON module for Lua 5.1/5.2
|
||||
========================================
|
||||
|
||||
*Version 2.1*
|
||||
|
||||
This module writes no global values, not even the module table.
|
||||
Import it using
|
||||
|
||||
json = require ("dkjson")
|
||||
|
||||
Exported functions and values:
|
||||
|
||||
`json.encode (object [, state])`
|
||||
--------------------------------
|
||||
|
||||
Create a string representing the object. `Object` can be a table,
|
||||
a string, a number, a boolean, `nil`, `json.null` or any object with
|
||||
a function `__tojson` in its metatable. A table can only use strings
|
||||
and numbers as keys and its values have to be valid objects as
|
||||
well. It raises an error for any invalid data types or reference
|
||||
cycles.
|
||||
|
||||
`state` is an optional table with the following fields:
|
||||
|
||||
- `indent`
|
||||
When `indent` (a boolean) is set, the created string will contain
|
||||
newlines and indentations. Otherwise it will be one long line.
|
||||
- `keyorder`
|
||||
`keyorder` is an array to specify the ordering of keys in the
|
||||
encoded output. If an object has keys which are not in this array
|
||||
they are written after the sorted keys.
|
||||
- `level`
|
||||
This is the initial level of indentation used when `indent` is
|
||||
set. For each level two spaces are added. When absent it is set
|
||||
to 0.
|
||||
- `buffer`
|
||||
`buffer` is an array to store the strings for the result so they
|
||||
can be concatenated at once. When it isn't given, the encode
|
||||
function will create it temporary and will return the
|
||||
concatenated result.
|
||||
- `bufferlen`
|
||||
When `bufferlen` is set, it has to be the index of the last
|
||||
element of `buffer`.
|
||||
- `tables`
|
||||
`tables` is a set to detect reference cycles. It is created
|
||||
temporary when absent. Every table that is currently processed
|
||||
is used as key, the value is `true`.
|
||||
|
||||
When `state.buffer` was set, the return value will be `true` on
|
||||
success. Without `state.buffer` the return value will be a string.
|
||||
|
||||
`json.decode (string [, position [, null]])`
|
||||
--------------------------------------------
|
||||
|
||||
Decode `string` starting at `position` or at 1 if `position` was
|
||||
omitted.
|
||||
|
||||
`null` is an optional value to be returned for null values. The
|
||||
default is `nil`, but you could set it to `json.null` or any other
|
||||
value.
|
||||
|
||||
The return values are the object or `nil`, the position of the next
|
||||
character that doesn't belong to the object, and in case of errors
|
||||
an error message.
|
||||
|
||||
Two metatables are created. Every array or object that is decoded gets
|
||||
a metatable with the `__jsontype` field set to either `array` or
|
||||
`object`. If you want to provide your own metatables use the syntax
|
||||
|
||||
json.decode (string, position, null, objectmeta, arraymeta)
|
||||
|
||||
`<metatable>.__jsonorder`
|
||||
-------------------------
|
||||
|
||||
`__jsonorder` can overwrite the `keyorder` for a specific table.
|
||||
|
||||
`<metatable>.__jsontype`
|
||||
------------------------
|
||||
|
||||
`__jsontype` can be either `"array"` or `"object"`. This is mainly useful
|
||||
for tables that can be empty. (The default for empty tables is
|
||||
`"array"`).
|
||||
|
||||
`<metatable>.__tojson (self, state)`
|
||||
------------------------------------
|
||||
|
||||
You can provide your own `__tojson` function in a metatable. In this
|
||||
function you can either add directly to the buffer and return true,
|
||||
or you can return a string. On errors nil and a message should be
|
||||
returned.
|
||||
|
||||
`json.null`
|
||||
-----------
|
||||
|
||||
You can use this value for setting explicit `null` values.
|
||||
|
||||
`json.version`
|
||||
--------------
|
||||
|
||||
Set to `"dkjson 2.1"`.
|
||||
|
||||
`json.quotestring (string)`
|
||||
---------------------------
|
||||
|
||||
Quote a UTF-8 string and escape critical characters using JSON
|
||||
escape sequences. This function is only necessary when you build
|
||||
your own `__tojson` functions.
|
||||
|
||||
`json.addnewline (state)`
|
||||
-------------------------
|
||||
|
||||
When `state.indent` is set, add a newline to `state.buffer` and spaces
|
||||
according to `state.level`.
|
||||
|
||||
LPeg support
|
||||
------------
|
||||
|
||||
When the local configuration variable
|
||||
`always_try_using_lpeg` is set, this module tries to load LPeg to
|
||||
replace the functions `quotestring` and `decode`. The speed increase
|
||||
is significant. You can get the LPeg module at
|
||||
<http://www.inf.puc-rio.br/~roberto/lpeg/>.
|
||||
When LPeg couldn't be loaded, the pure Lua functions stay active.
|
||||
|
||||
In case you don't want this module to require LPeg on its own,
|
||||
disable this option:
|
||||
|
||||
--]==]
|
||||
local always_try_using_lpeg = true
|
||||
--[==[
|
||||
|
||||
In this case you can later load LPeg support using
|
||||
|
||||
### `json.use_lpeg ()`
|
||||
|
||||
Require the LPeg module and replace the functions `quotestring` and
|
||||
and `decode` with functions that use LPeg patterns.
|
||||
This function returns the module table, so you can load the module
|
||||
using:
|
||||
|
||||
json = require "dkjson".use_lpeg()
|
||||
|
||||
Alternatively you can use `pcall` so the JSON module still works when
|
||||
LPeg isn't found.
|
||||
|
||||
json = require "dkjson"
|
||||
pcall (json.use_lpeg)
|
||||
|
||||
### `json.using_lpeg`
|
||||
|
||||
This variable is set to `true` when LPeg was loaded successfully.
|
||||
|
||||
You can contact the author by sending an e-mail to 'kolf' at the
|
||||
e-mail provider 'gmx.de'.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
*Copyright (C) 2010, 2011 David Heiko Kolf*
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
<!-- This documentation can be parsed using Markdown to generate HTML.
|
||||
The source code is enclosed in a HTML comment so it won't be displayed
|
||||
by browsers, but it should be removed from the final HTML file as
|
||||
it isn't a valid HTML comment (and wastes space).
|
||||
-->
|
||||
|
||||
<!--]==]
|
||||
|
||||
-- global dependencies:
|
||||
local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
|
||||
pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
|
||||
local error, require, pcall = error, require, pcall
|
||||
local floor, huge = math.floor, math.huge
|
||||
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
|
||||
string.rep, string.gsub, string.sub, string.byte, string.char,
|
||||
string.find, string.len, string.format
|
||||
local concat = table.concat
|
||||
|
||||
if _VERSION == 'Lua 5.1' then
|
||||
local function noglobals (s,k,v) error ("global access: " .. k, 2) end
|
||||
setfenv (1, setmetatable ({}, { __index = noglobals, __newindex = noglobals }))
|
||||
end
|
||||
local _ENV = nil -- blocking globals in Lua 5.2
|
||||
|
||||
local json = { version = "dkjson 2.1" }
|
||||
|
||||
pcall (function()
|
||||
-- Enable access to blocked metatables.
|
||||
-- Don't worry, this module doesn't change anything in them.
|
||||
local debmeta = require "debug".getmetatable
|
||||
if debmeta then getmetatable = debmeta end
|
||||
end)
|
||||
|
||||
json.null = setmetatable ({}, {
|
||||
__tojson = function () return "null" end
|
||||
})
|
||||
|
||||
local function isarray (tbl)
|
||||
local max, n, arraylen = 0, 0, 0
|
||||
for k,v in pairs (tbl) do
|
||||
if k == 'n' and type(v) == 'number' then
|
||||
arraylen = v
|
||||
if v > max then
|
||||
max = v
|
||||
end
|
||||
else
|
||||
if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
|
||||
return false
|
||||
end
|
||||
if k > max then
|
||||
max = k
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
if max > 10 and max > arraylen and max > n * 2 then
|
||||
return false -- don't create an array with too many holes
|
||||
end
|
||||
return true, max
|
||||
end
|
||||
|
||||
local escapecodes = {
|
||||
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
|
||||
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
|
||||
}
|
||||
|
||||
local function escapeutf8 (uchar)
|
||||
local value = escapecodes[uchar]
|
||||
if value then
|
||||
return value
|
||||
end
|
||||
local a, b, c, d = strbyte (uchar, 1, 4)
|
||||
a, b, c, d = a or 0, b or 0, c or 0, d or 0
|
||||
if a <= 0x7f then
|
||||
value = a
|
||||
elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
|
||||
value = (a - 0xc0) * 0x40 + b - 0x80
|
||||
elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
|
||||
value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
|
||||
elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
|
||||
value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
|
||||
else
|
||||
return ""
|
||||
end
|
||||
if value <= 0xffff then
|
||||
return strformat ("\\u%.4x", value)
|
||||
elseif value <= 0x10ffff then
|
||||
-- encode as UTF-16 surrogate pair
|
||||
value = value - 0x10000
|
||||
local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400)
|
||||
return strformat ("\\u%.4x\\u%.4x", highsur, lowsur)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function fsub (str, pattern, repl)
|
||||
-- gsub always builds a new string in a buffer, even when no match
|
||||
-- exists. First using find should be more efficient when most strings
|
||||
-- don't contain the pattern.
|
||||
if strfind (str, pattern) then
|
||||
return gsub (str, pattern, repl)
|
||||
else
|
||||
return str
|
||||
end
|
||||
end
|
||||
|
||||
local function quotestring (value)
|
||||
-- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
|
||||
value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8)
|
||||
if strfind (value, "[\194\216\220\225\226\239]") then
|
||||
value = fsub (value, "\194[\128-\159\173]", escapeutf8)
|
||||
value = fsub (value, "\216[\128-\132]", escapeutf8)
|
||||
value = fsub (value, "\220\143", escapeutf8)
|
||||
value = fsub (value, "\225\158[\180\181]", escapeutf8)
|
||||
value = fsub (value, "\226\128[\140-\143\168\175]", escapeutf8)
|
||||
value = fsub (value, "\226\129[\160-\175]", escapeutf8)
|
||||
value = fsub (value, "\239\187\191", escapeutf8)
|
||||
value = fsub (value, "\239\191[\176\191]", escapeutf8)
|
||||
end
|
||||
return "\"" .. value .. "\""
|
||||
end
|
||||
json.quotestring = quotestring
|
||||
|
||||
local function addnewline2 (level, buffer, buflen)
|
||||
buffer[buflen+1] = "\n"
|
||||
buffer[buflen+2] = strrep (" ", level)
|
||||
buflen = buflen + 2
|
||||
return buflen
|
||||
end
|
||||
|
||||
function json.addnewline (state)
|
||||
if state.indent then
|
||||
state.bufferlen = addnewline2 (state.level or 0,
|
||||
state.buffer, state.bufferlen or #(state.buffer))
|
||||
end
|
||||
end
|
||||
|
||||
local encode2 -- forward declaration
|
||||
|
||||
local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
local kt = type (key)
|
||||
if kt ~= 'string' and kt ~= 'number' then
|
||||
return nil, "type '" .. kt .. "' is not supported as a key by JSON."
|
||||
end
|
||||
if prev then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = ","
|
||||
end
|
||||
if indent then
|
||||
buflen = addnewline2 (level, buffer, buflen)
|
||||
end
|
||||
buffer[buflen+1] = quotestring (key)
|
||||
buffer[buflen+2] = ":"
|
||||
return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder)
|
||||
end
|
||||
|
||||
encode2 = function (value, indent, level, buffer, buflen, tables, globalorder)
|
||||
local valtype = type (value)
|
||||
local valmeta = getmetatable (value)
|
||||
valmeta = type (valmeta) == 'table' and valmeta -- only tables
|
||||
local valtojson = valmeta and valmeta.__tojson
|
||||
if valtojson then
|
||||
if tables[value] then
|
||||
return nil, "reference cycle"
|
||||
end
|
||||
tables[value] = true
|
||||
local state = {
|
||||
indent = indent, level = level, buffer = buffer,
|
||||
bufferlen = buflen, tables = tables, keyorder = globalorder
|
||||
}
|
||||
local ret, msg = valtojson (value, state)
|
||||
if not ret then return nil, msg end
|
||||
tables[value] = nil
|
||||
buflen = state.bufferlen
|
||||
if type (ret) == 'string' then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = ret
|
||||
end
|
||||
elseif value == nil then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "null"
|
||||
elseif valtype == 'number' then
|
||||
local s
|
||||
if value ~= value or value >= huge or -value >= huge then
|
||||
-- This is the behaviour of the original JSON implementation.
|
||||
s = "null"
|
||||
else
|
||||
s = tostring (value)
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = s
|
||||
elseif valtype == 'boolean' then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = value and "true" or "false"
|
||||
elseif valtype == 'string' then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = quotestring (value)
|
||||
elseif valtype == 'table' then
|
||||
if tables[value] then
|
||||
return nil, "reference cycle"
|
||||
end
|
||||
tables[value] = true
|
||||
level = level + 1
|
||||
local metatype = valmeta and valmeta.__jsontype
|
||||
local isa, n
|
||||
if metatype == 'array' then
|
||||
isa = true
|
||||
n = value.n or #value
|
||||
elseif metatype == 'object' then
|
||||
isa = false
|
||||
else
|
||||
isa, n = isarray (value)
|
||||
end
|
||||
local msg
|
||||
if isa then -- JSON array
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "["
|
||||
for i = 1, n do
|
||||
buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder)
|
||||
if not buflen then return nil, msg end
|
||||
if i < n then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = ","
|
||||
end
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "]"
|
||||
else -- JSON object
|
||||
local prev = false
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "{"
|
||||
local order = valmeta and valmeta.__jsonorder or globalorder
|
||||
if order then
|
||||
local used = {}
|
||||
n = #order
|
||||
for i = 1, n do
|
||||
local k = order[i]
|
||||
local v = value[k]
|
||||
if v then
|
||||
used[k] = true
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
for k,v in pairs (value) do
|
||||
if not used[k] then
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
if not buflen then return nil, msg end
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
else -- unordered
|
||||
for k,v in pairs (value) do
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
if not buflen then return nil, msg end
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
if indent then
|
||||
buflen = addnewline2 (level - 1, buffer, buflen)
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "}"
|
||||
end
|
||||
tables[value] = nil
|
||||
else
|
||||
return nil, "type '" .. valtype .. "' is not supported by JSON."
|
||||
end
|
||||
return buflen
|
||||
end
|
||||
|
||||
function json.encode (value, state)
|
||||
state = state or {}
|
||||
local oldbuffer = state.buffer
|
||||
local buffer = oldbuffer or {}
|
||||
local ret, msg = encode2 (value, state.indent, state.level or 0,
|
||||
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder)
|
||||
if not ret then
|
||||
error (msg, 2)
|
||||
elseif oldbuffer then
|
||||
state.bufferlen = ret
|
||||
return true
|
||||
else
|
||||
return concat (buffer)
|
||||
end
|
||||
end
|
||||
|
||||
local function loc (str, where)
|
||||
local line, pos, linepos = 1, 1, 1
|
||||
while true do
|
||||
pos = strfind (str, "\n", pos, true)
|
||||
if pos and pos < where then
|
||||
line = line + 1
|
||||
linepos = pos
|
||||
pos = pos + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
return "line " .. line .. ", column " .. (where - linepos)
|
||||
end
|
||||
|
||||
local function unterminated (str, what, where)
|
||||
return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where)
|
||||
end
|
||||
|
||||
local function scanwhite (str, pos)
|
||||
while true do
|
||||
pos = strfind (str, "%S", pos)
|
||||
if not pos then return nil end
|
||||
if strsub (str, pos, pos + 2) == "\239\187\191" then
|
||||
-- UTF-8 Byte Order Mark
|
||||
pos = pos + 3
|
||||
else
|
||||
return pos
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local escapechars = {
|
||||
["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f",
|
||||
["n"] = "\n", ["r"] = "\r", ["t"] = "\t"
|
||||
}
|
||||
|
||||
local function unichar (value)
|
||||
if value < 0 then
|
||||
return nil
|
||||
elseif value <= 0x007f then
|
||||
return strchar (value)
|
||||
elseif value <= 0x07ff then
|
||||
return strchar (0xc0 + floor(value/0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
elseif value <= 0xffff then
|
||||
return strchar (0xe0 + floor(value/0x1000),
|
||||
0x80 + (floor(value/0x40) % 0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
elseif value <= 0x10ffff then
|
||||
return strchar (0xf0 + floor(value/0x40000),
|
||||
0x80 + (floor(value/0x1000) % 0x40),
|
||||
0x80 + (floor(value/0x40) % 0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function scanstring (str, pos)
|
||||
local lastpos = pos + 1
|
||||
local buffer, n = {}, 0
|
||||
while true do
|
||||
local nextpos = strfind (str, "[\"\\]", lastpos)
|
||||
if not nextpos then
|
||||
return unterminated (str, "string", pos)
|
||||
end
|
||||
if nextpos > lastpos then
|
||||
n = n + 1
|
||||
buffer[n] = strsub (str, lastpos, nextpos - 1)
|
||||
end
|
||||
if strsub (str, nextpos, nextpos) == "\"" then
|
||||
lastpos = nextpos + 1
|
||||
break
|
||||
else
|
||||
local escchar = strsub (str, nextpos + 1, nextpos + 1)
|
||||
local value
|
||||
if escchar == "u" then
|
||||
value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16)
|
||||
if value then
|
||||
local value2
|
||||
if 0xD800 <= value and value <= 0xDBff then
|
||||
-- we have the high surrogate of UTF-16. Check if there is a
|
||||
-- low surrogate escaped nearby to combine them.
|
||||
if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then
|
||||
value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16)
|
||||
if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
|
||||
value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
|
||||
else
|
||||
value2 = nil -- in case it was out of range for a low surrogate
|
||||
end
|
||||
end
|
||||
end
|
||||
value = value and unichar (value)
|
||||
if value then
|
||||
if value2 then
|
||||
lastpos = nextpos + 12
|
||||
else
|
||||
lastpos = nextpos + 6
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not value then
|
||||
value = escapechars[escchar] or escchar
|
||||
lastpos = nextpos + 2
|
||||
end
|
||||
n = n + 1
|
||||
buffer[n] = value
|
||||
end
|
||||
end
|
||||
if n == 1 then
|
||||
return buffer[1], lastpos
|
||||
elseif n > 1 then
|
||||
return concat (buffer), lastpos
|
||||
else
|
||||
return "", lastpos
|
||||
end
|
||||
end
|
||||
|
||||
local scanvalue -- forward declaration
|
||||
|
||||
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
|
||||
local len = strlen (str)
|
||||
local tbl, n = {}, 0
|
||||
local pos = startpos + 1
|
||||
if what == 'object' then
|
||||
setmetatable (tbl, objectmeta)
|
||||
else
|
||||
setmetatable (tbl, arraymeta)
|
||||
end
|
||||
while true do
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
local char = strsub (str, pos, pos)
|
||||
if char == closechar then
|
||||
return tbl, pos + 1
|
||||
end
|
||||
local val1, err
|
||||
val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then return nil, pos, err end
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
char = strsub (str, pos, pos)
|
||||
if char == ":" then
|
||||
if val1 == nil then
|
||||
return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")"
|
||||
end
|
||||
pos = scanwhite (str, pos + 1)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
local val2
|
||||
val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then return nil, pos, err end
|
||||
tbl[val1] = val2
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
char = strsub (str, pos, pos)
|
||||
else
|
||||
n = n + 1
|
||||
tbl[n] = val1
|
||||
end
|
||||
if char == "," then
|
||||
pos = pos + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
|
||||
pos = pos or 1
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then
|
||||
return nil, strlen (str) + 1, "no valid JSON value (reached the end)"
|
||||
end
|
||||
local char = strsub (str, pos, pos)
|
||||
if char == "{" then
|
||||
return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta)
|
||||
elseif char == "[" then
|
||||
return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta)
|
||||
elseif char == "\"" then
|
||||
return scanstring (str, pos)
|
||||
else
|
||||
local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
|
||||
if pstart then
|
||||
local number = tonumber (strsub (str, pstart, pend))
|
||||
if number then
|
||||
return number, pend + 1
|
||||
end
|
||||
end
|
||||
pstart, pend = strfind (str, "^%a%w*", pos)
|
||||
if pstart then
|
||||
local name = strsub (str, pstart, pend)
|
||||
if name == "true" then
|
||||
return true, pend + 1
|
||||
elseif name == "false" then
|
||||
return false, pend + 1
|
||||
elseif name == "null" then
|
||||
return nullval, pend + 1
|
||||
end
|
||||
end
|
||||
return nil, pos, "no valid JSON value at " .. loc (str, pos)
|
||||
end
|
||||
end
|
||||
|
||||
function json.decode (str, pos, nullval, objectmeta, arraymeta)
|
||||
objectmeta = objectmeta or {__jsontype = 'object'}
|
||||
arraymeta = arraymeta or {__jsontype = 'array'}
|
||||
return scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
end
|
||||
|
||||
function json.use_lpeg ()
|
||||
local g = require ("lpeg")
|
||||
local pegmatch = g.match
|
||||
local P, S, R, V = g.P, g.S, g.R, g.V
|
||||
|
||||
local SpecialChars = (R"\0\31" + S"\"\\\127" +
|
||||
P"\194" * (R"\128\159" + P"\173") +
|
||||
P"\216" * R"\128\132" +
|
||||
P"\220\132" +
|
||||
P"\225\158" * S"\180\181" +
|
||||
P"\226\128" * (R"\140\143" + S"\168\175") +
|
||||
P"\226\129" * R"\160\175" +
|
||||
P"\239\187\191" +
|
||||
P"\229\191" + R"\176\191") / escapeutf8
|
||||
|
||||
local QuoteStr = g.Cs (g.Cc "\"" * (SpecialChars + 1)^0 * g.Cc "\"")
|
||||
|
||||
quotestring = function (str)
|
||||
return pegmatch (QuoteStr, str)
|
||||
end
|
||||
json.quotestring = quotestring
|
||||
|
||||
local function ErrorCall (str, pos, msg, state)
|
||||
if not state.msg then
|
||||
state.msg = msg .. " at " .. loc (str, pos)
|
||||
state.pos = pos
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function Err (msg)
|
||||
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
|
||||
end
|
||||
|
||||
local Space = (S" \n\r\t" + P"\239\187\191")^0
|
||||
|
||||
local PlainChar = 1 - S"\"\\\n\r"
|
||||
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
|
||||
local HexDigit = R("09", "af", "AF")
|
||||
local function UTF16Surrogate (match, pos, high, low)
|
||||
high, low = tonumber (high, 16), tonumber (low, 16)
|
||||
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
|
||||
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
local function UTF16BMP (hex)
|
||||
return unichar (tonumber (hex, 16))
|
||||
end
|
||||
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
|
||||
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
|
||||
local Char = UnicodeEscape + EscapeSequence + PlainChar
|
||||
local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string")
|
||||
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
|
||||
local Fractal = P"." * R"09"^0
|
||||
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
|
||||
local Number = (Integer * Fractal^(-1) * Exponent^(-1))/tonumber
|
||||
local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1)
|
||||
local SimpleValue = Number + String + Constant
|
||||
local ArrayContent, ObjectContent
|
||||
|
||||
-- The functions parsearray and parseobject parse only a single value/pair
|
||||
-- at a time and store them directly to avoid hitting the LPeg limits.
|
||||
local function parsearray (str, pos, nullval, state)
|
||||
local obj, cont
|
||||
local npos
|
||||
local t, nt = {}, 0
|
||||
repeat
|
||||
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
|
||||
if not npos then break end
|
||||
pos = npos
|
||||
nt = nt + 1
|
||||
t[nt] = obj
|
||||
until cont == 'last'
|
||||
return pos, setmetatable (t, state.arraymeta)
|
||||
end
|
||||
|
||||
local function parseobject (str, pos, nullval, state)
|
||||
local obj, key, cont
|
||||
local npos
|
||||
local t = {}
|
||||
repeat
|
||||
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
|
||||
if not npos then break end
|
||||
pos = npos
|
||||
t[key] = obj
|
||||
until cont == 'last'
|
||||
return pos, setmetatable (t, state.objectmeta)
|
||||
end
|
||||
|
||||
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
|
||||
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
|
||||
local Value = Space * (Array + Object + SimpleValue)
|
||||
local ExpectedValue = Value + Space * Err "value expected"
|
||||
ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
|
||||
local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
|
||||
ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
|
||||
local DecodeValue = ExpectedValue * g.Cp ()
|
||||
|
||||
function json.decode (str, pos, nullval, objectmeta, arraymeta)
|
||||
local state = {
|
||||
objectmeta = objectmeta or {__jsontype = 'object'},
|
||||
arraymeta = arraymeta or {__jsontype = 'array'}
|
||||
}
|
||||
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
|
||||
if state.msg then
|
||||
return nil, state.pos, state.msg
|
||||
else
|
||||
return obj, retpos
|
||||
end
|
||||
end
|
||||
|
||||
-- use this function only once:
|
||||
json.use_lpeg = function () return json end
|
||||
|
||||
json.using_lpeg = true
|
||||
|
||||
return json -- so you can get the module using json = require "dkjson".use_lpeg()
|
||||
end
|
||||
|
||||
if always_try_using_lpeg then
|
||||
pcall (json.use_lpeg)
|
||||
end
|
||||
|
||||
return json
|
||||
|
||||
-->
|
||||
@@ -1,96 +0,0 @@
|
||||
function HTML_ToText (text)
|
||||
-- Declare variables, load the file. Make tags lowercase.
|
||||
text = string.gsub (text,"(%b<>)",
|
||||
function (tag)
|
||||
return tag:lower()
|
||||
end)
|
||||
--[[
|
||||
First we kill the developer formatting (tabs, CR, LF)
|
||||
and produce a long string with no newlines and tabs.
|
||||
We also kill repeated spaces as browsers ignore them anyway.
|
||||
]]
|
||||
local devkill=
|
||||
{
|
||||
["("..string.char(10)..")"] = " ",
|
||||
["("..string.char(13)..")"] = " ",
|
||||
["("..string.char(15)..")"] = "",
|
||||
["(%s%s+)"]=" ",
|
||||
}
|
||||
for pat, res in pairs (devkill) do
|
||||
text = string.gsub (text, pat, res)
|
||||
end
|
||||
-- Then we remove the header. We do this by stripping it first.
|
||||
text = string.gsub (text, "(<%s*head[^>]*>)", "<head>")
|
||||
text = string.gsub (text, "(<%s*%/%s*head%s*>)", "</head>")
|
||||
text = string.gsub (text, "(<head>,*<%/head>)", "")
|
||||
-- Kill all scripts. First we nuke their attribs.
|
||||
text = string.gsub (text, "(<%s*script[^>]*>)", "<script>")
|
||||
text = string.gsub (text, "(<%s*%/%s*script%s*>)", "</script>")
|
||||
text = string.gsub (text, "(<script>,*<%/script>)", "")
|
||||
-- Ok, same for styles.
|
||||
text = string.gsub (text, "(<%s*style[^>]*>)", "<style>")
|
||||
text = string.gsub (text, "(<%s*%/%s*style%s*>)", "</style>")
|
||||
text = string.gsub (text, "(<style>.*<%/style>)", "")
|
||||
|
||||
-- Replace <td> with tabulators.
|
||||
text = string.gsub (text, "(<%s*td[^>]*>)","\t")
|
||||
|
||||
-- Replace <br> with linebreaks.
|
||||
text = string.gsub (text, "(<%s*br%s*%/%s*>)","\n")
|
||||
|
||||
-- Replace <li> with an asterisk surrounded by 2 spaces.
|
||||
-- Replace </li> with a newline.
|
||||
text = string.gsub (text, "(<%s*li%s*%s*>)"," * ")
|
||||
text = string.gsub (text, "(<%s*/%s*li%s*%s*>)","\n")
|
||||
|
||||
-- <p>, <div>, <tr>, <ul> will be replaced to a double newline.
|
||||
text = string.gsub (text, "(<%s*div[^>]*>)", "\n\n")
|
||||
text = string.gsub (text, "(<%s*p[^>]*>)", "\n\n")
|
||||
text = string.gsub (text, "(<%s*tr[^>]*>)", "\n\n")
|
||||
text = string.gsub (text, "(<%s*%/*%s*ul[^>]*>)", "\n\n")
|
||||
--
|
||||
|
||||
-- Nuke all other tags now.
|
||||
text = string.gsub (text, "(%b<>)","")
|
||||
|
||||
-- Replace entities to their correspondant stuff where applicable.
|
||||
-- C# is owned badly here by using a table. :-P
|
||||
-- A metatable secures entities, so you can add them natively as keys.
|
||||
-- Enclosing brackets also get added automatically (capture!)
|
||||
local entities = {}
|
||||
setmetatable (entities,
|
||||
{
|
||||
__newindex = function (tbl, key, value)
|
||||
key = string.gsub (key, "(%#)" , "%%#")
|
||||
key = string.gsub (key, "(%&)" , "%%&")
|
||||
key = string.gsub (key, "(%;)" , "%%;")
|
||||
key = string.gsub (key, "(.+)" , "("..key..")")
|
||||
rawset (tbl, key, value)
|
||||
end
|
||||
})
|
||||
entities =
|
||||
{
|
||||
[" "] = " ",
|
||||
["•"] = " * ",
|
||||
["?"] = "<",
|
||||
["?"] = ">",
|
||||
["™"] = "(tm)",
|
||||
["⁄"] = "/",
|
||||
["<"] = "<",
|
||||
[">"] = ">",
|
||||
["©"] = "(c)",
|
||||
["®"] = "(r)",
|
||||
-- Then kill all others.
|
||||
-- You can customize this table if you would like to,
|
||||
-- I just got bored of copypasting. :-)
|
||||
-- http://hotwired.lycos.com/webmonkey/reference/special_characters/
|
||||
["%&.+%;"] = "",
|
||||
}
|
||||
for entity, repl in pairs (entities) do
|
||||
text = string.gsub (text, entity, repl)
|
||||
end
|
||||
|
||||
return text
|
||||
|
||||
end
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
local function backButtonRelease( self, event )
|
||||
storyboard.gotoScene(true, "login", "zoomInOut", 200)
|
||||
end
|
||||
|
||||
local viewController = require("viewController")
|
||||
local mainView, tabView, currentScreen, tabBar
|
||||
|
||||
local function loadScreen(newScreen)
|
||||
if currentScreen then
|
||||
currentScreen:cleanUp()
|
||||
end
|
||||
currentScreen = require(newScreen).createScreen()
|
||||
tabView:insert(currentScreen)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Handler that gets notified when the exit alert closes
|
||||
local function exitListener(event)
|
||||
if "clicked" == event.action then
|
||||
local i = event.index
|
||||
if 1 == i then
|
||||
os.exit()
|
||||
elseif 2 == i then
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function showScreen(event)
|
||||
local t = event.target
|
||||
local phase = event.phase
|
||||
|
||||
if phase == "ended" then
|
||||
if t.id == 1 then
|
||||
loadScreen("myTodo")
|
||||
elseif t.id == 2 then
|
||||
loadScreen("myTask")
|
||||
elseif t.id == 3 then
|
||||
loadScreen("myBug")
|
||||
elseif t.id == 4 then
|
||||
native.showAlert("提示", "要退出吗?", {"确定", "取消"}, exitListener)
|
||||
end
|
||||
tabBar.selected(t)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function scene:createScene( event )
|
||||
local screenGroup = self.view
|
||||
|
||||
local backgroundImg = display.newImage("background.png")
|
||||
backgroundImg.xOrigin = display.contentWidth/2
|
||||
backgroundImg.yOrigin = display.contentHeight/2
|
||||
screenGroup:insert(backgroundImg)
|
||||
|
||||
local screenGroup = self.view
|
||||
tabView = display.newGroup()
|
||||
screenGroup:insert(tabView)
|
||||
|
||||
loadScreen("myTodo")
|
||||
|
||||
tabBar = viewController.newTabBar{
|
||||
background = "tabBar.png",
|
||||
tabs = {"Todo", "任务", "Bug", "退出"},
|
||||
onRelease = showScreen
|
||||
}
|
||||
screenGroup:insert(tabBar)
|
||||
|
||||
tabBar.selected()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function scene:enterScene( event )
|
||||
storyboard.removeScene('login')
|
||||
storyboard.removeScene('viewTodo')
|
||||
storyboard.removeScene('viewTask')
|
||||
storyboard.removeScene('viewBug')
|
||||
end
|
||||
|
||||
function scene:exitScene()
|
||||
end
|
||||
|
||||
function scene:destroyScene(event)
|
||||
end
|
||||
|
||||
scene:addEventListener("createScene", scene)
|
||||
scene:addEventListener("enterScene", scene)
|
||||
scene:addEventListener("exitScene", scene)
|
||||
scene:addEventListener("destroyScene", scene)
|
||||
|
||||
return scene
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,206 +0,0 @@
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
local zentaoImg
|
||||
local accountText, passwordText, zentaoRootText
|
||||
local accountField, passwordField, zentaoRootField
|
||||
local loginButton
|
||||
local fontSize = 14
|
||||
|
||||
local userData = {}
|
||||
|
||||
local zentaoRoot = "http://"
|
||||
local configAPI = ""
|
||||
local account = ""
|
||||
local password = ""
|
||||
local md5Password = ""
|
||||
local mixPassword = ""
|
||||
|
||||
-- global vars
|
||||
loginAPI = ""
|
||||
sessionAPI = ""
|
||||
myTodoAPI = ""
|
||||
myBugAPI = ""
|
||||
myTaskAPI = ""
|
||||
|
||||
config = {}
|
||||
session = {}
|
||||
|
||||
navBar = nil
|
||||
navHeader = nil
|
||||
|
||||
local function loginButtonRelease( self, event )
|
||||
if string.len(zentaoRootField.text) > 0 and string.len(accountField.text) > 0 and string.len(passwordField.text) > 0 then
|
||||
account = accountField.text
|
||||
password = passwordField.text
|
||||
if string.find(zentaoRootField.text, "http://") then
|
||||
zentaoRoot = zentaoRootField.text
|
||||
else
|
||||
zentaoRoot = zentaoRoot .. zentaoRootField.text
|
||||
end
|
||||
|
||||
if string.find(zentaoRoot, '/', string.len("http://")+1) == nil then
|
||||
zentaoRoot = zentaoRoot .. '/'
|
||||
end
|
||||
configAPI = zentaoRoot .. "?mode=getconfig"
|
||||
|
||||
local response = {}
|
||||
-- get the config
|
||||
local result = http.request {url = configAPI, method = "GET", sink = ltn12.sink.table(response) }
|
||||
|
||||
if table.getn(response) == 0 then
|
||||
native.showAlert("提示", "网络错误,请查看网络或重新设置!", {"我知道了"} )
|
||||
else
|
||||
for i, val in pairs(response) do
|
||||
config = json.decode(val)
|
||||
end
|
||||
|
||||
-- set APIs
|
||||
if config.requestType == "GET" then
|
||||
loginAPI = zentaoRoot .. "?m=user&f=login"
|
||||
sessionAPI = zentaoRoot .. "?m=api&f=getSessionID&t=json"
|
||||
|
||||
myTodoAPI = zentaoRoot .. "?m=my&f=todo&t=json"
|
||||
myTaskAPI = zentaoRoot .. "?m=my&f=task&t=json"
|
||||
myBugAPI = zentaoRoot .. "?m=my&f=bug&t=json"
|
||||
elseif config.requestType == "PATH_INFO" then
|
||||
loginAPI = zentaoRoot .. "user-login.json?a=1"
|
||||
sessionAPI = zentaoRoot .. "api-getsessionid.json?a=1"
|
||||
|
||||
myTodoAPI = zentaoRoot .. "my-todo.json?a=1"
|
||||
myTaskAPI = zentaoRoot .. "my-task.json?a=1"
|
||||
myBugAPI = zentaoRoot .. "my-bug.json?a=1"
|
||||
end
|
||||
|
||||
-- get the session
|
||||
http.request{url = sessionAPI, method = "GET", sink = ltn12.sink.table(session)}
|
||||
|
||||
if table.getn(session) == 0 then
|
||||
native.showAlert("提示", "网络错误,请查看网络或重新设置!", {"我知道了"} )
|
||||
else
|
||||
session = json.decode(table.concat(session))
|
||||
session.data = json.decode(session.data)
|
||||
|
||||
-- user login
|
||||
local response2 = {}
|
||||
md5Password = crypto.digest(crypto.md5, password)
|
||||
mixPassword = crypto.digest(crypto.md5, crypto.digest(crypto.md5, password) .. session.data.rand)
|
||||
|
||||
loginAPI = loginAPI .. "&account=" .. account .. "&password=" .. mixPassword .. "&" .. session.data.sessionName .. "=" .. session.data.sessionID
|
||||
http.request{url = loginAPI, method = "GET", sink = ltn12.sink.table(response2) }
|
||||
|
||||
if json.decode(table.concat(response2)).status == "failed" then
|
||||
native.showAlert("登录失败", "网络问题,或用户信息设置错误!", {"我知道了"})
|
||||
else
|
||||
local userData = json.encode({zentaoRoot = zentaoRoot, account = account, md5Password = md5Password})
|
||||
local path = system.pathForFile( "config.txt", system.DocumentsDirectory )
|
||||
local file = io.open(path, "w+")
|
||||
local result = file:write(userData)
|
||||
io.close( file )
|
||||
|
||||
storyboard.gotoScene(true, "index", "slideLeft", 100)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
native.showAlert("提示", "请输入完整的用户信息!", {"我知道了"} )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function scene:createScene( event )
|
||||
local screenGroup = self.view
|
||||
|
||||
zentaoImg = display.newImage("zentao.png")
|
||||
zentaoImg.xOrigin = display.contentWidth/2
|
||||
zentaoImg.yOrigin = display.contentHeight/2
|
||||
screenGroup:insert(zentaoImg)
|
||||
end
|
||||
|
||||
-- Called immediately after scene has moved onscreen:
|
||||
function scene:enterScene(event)
|
||||
local screenGroup = self.view
|
||||
|
||||
navBar = display.newImage("navBar.png")
|
||||
navBar.xOrigin = display.contentWidth/2 + display.screenOriginX
|
||||
navBar.yOrigin = navBar.yOrigin + display.screenOriginY
|
||||
screenGroup:insert(navBar)
|
||||
|
||||
navHeader = display.newText("禅道", 0, 0, native.systemFontBold, 18)
|
||||
navHeader:setTextColor(255, 255, 255)
|
||||
navHeader.xOrigin = display.contentWidth/2
|
||||
navHeader.yOrigin = navBar.yOrigin
|
||||
screenGroup:insert(navHeader)
|
||||
|
||||
local objectX = display.contentWidth /8
|
||||
local objectY = display.contentWidth / 3
|
||||
local textFieldWidth = math.floor(display.contentWidth*2/3)
|
||||
local textFieldHeight = 38
|
||||
|
||||
-- account
|
||||
accountText = display.newText("用户名:", objectX, objectY, native.systemFontBold, fontSize)
|
||||
accountText:setTextColor(0,0,0)
|
||||
screenGroup:insert(accountText)
|
||||
objectY = objectY + accountText.height
|
||||
|
||||
accountField = native.newTextField(objectX, objectY, textFieldWidth, textFieldHeight)
|
||||
accountField.text = account
|
||||
screenGroup:insert(accountField)
|
||||
objectY = objectY + accountField.height
|
||||
|
||||
-- password
|
||||
passwordText = display.newText("密码:", objectX, objectY , native.systemFontBold, fontSize)
|
||||
passwordText:setTextColor(0,0,0)
|
||||
screenGroup:insert(passwordText)
|
||||
objectY = objectY + passwordText.height
|
||||
|
||||
passwordField = native.newTextField(objectX, objectY, textFieldWidth, textFieldHeight)
|
||||
passwordField.text = password
|
||||
passwordField.isSecure = true
|
||||
screenGroup:insert(passwordField)
|
||||
objectY = objectY + passwordField.height
|
||||
|
||||
-- zentaoRoot
|
||||
zentaoRootText = display.newText("访问地址:", objectX, objectY, native.systemFontBold, fontSize)
|
||||
zentaoRootText:setTextColor(0,0,0)
|
||||
screenGroup:insert(zentaoRootText)
|
||||
objectY = objectY + zentaoRootText.height
|
||||
|
||||
zentaoRootField = native.newTextField(objectX, objectY, textFieldWidth, textFieldHeight)
|
||||
zentaoRootField.text = zentaoRoot
|
||||
screenGroup:insert(zentaoRootField)
|
||||
objectY = objectY + zentaoRootField.height
|
||||
|
||||
-- login button
|
||||
loginButton = ui.newButton
|
||||
{
|
||||
default = "button.png",
|
||||
over = "button_over.png",
|
||||
onRelease = loginButtonRelease,
|
||||
size = fontSize,
|
||||
text = "登录",
|
||||
textColor = {0, 0, 0, 165},
|
||||
emboss = true
|
||||
}
|
||||
loginButton.xOrigin = display.contentWidth/2
|
||||
loginButton.yOrigin = objectY + loginButton.height
|
||||
local tmpWidth = loginButton.width
|
||||
loginButton.width = math.floor(display.contentWidth/4)
|
||||
loginButton.height = math.floor(loginButton.width * loginButton.height / tmpWidth)
|
||||
screenGroup:insert(loginButton)
|
||||
|
||||
end
|
||||
|
||||
function scene:exitScene( event )
|
||||
end
|
||||
|
||||
function scene:destroyScene( event )
|
||||
end
|
||||
|
||||
scene:addEventListener("createScene", scene )
|
||||
scene:addEventListener("enterScene", scene )
|
||||
scene:addEventListener("exitScene", scene )
|
||||
scene:addEventListener("destroyScene", scene )
|
||||
|
||||
return scene
|
||||
@@ -1,31 +0,0 @@
|
||||
--- global vars
|
||||
storyboard = require "storyboard"
|
||||
http = require("socket.http")
|
||||
crypto = require("crypto")
|
||||
ltn12 = require("ltn12")
|
||||
url = require("socket.url")
|
||||
json = require("dkjson")
|
||||
ui = require("ui")
|
||||
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
display.setStatusBar(display.HiddenStatusBar)
|
||||
|
||||
local path = system.pathForFile("config.txt", system.DocumentsDirectory)
|
||||
local file = io.open(path, "r")
|
||||
|
||||
if file ~= nil then
|
||||
userData = file:read("*a")
|
||||
io.close(file)
|
||||
if userData then
|
||||
userData = json.decode(userData)
|
||||
zentaoRoot = userData.zentaoRoot
|
||||
account = userData.account
|
||||
md5Password = userData.md5Password
|
||||
configAPI = zentaoRoot .. "?mode=getconfig"
|
||||
|
||||
storyboard.gotoScene("autoLogin", "slideRight", 1)
|
||||
end
|
||||
else
|
||||
storyboard.gotoScene("login", "slideRight", 1)
|
||||
end
|
||||
@@ -1,115 +0,0 @@
|
||||
module(..., package.seeall)
|
||||
|
||||
-- global vars
|
||||
myBugs = {}
|
||||
currentBugID = nil
|
||||
|
||||
-- local vars
|
||||
local scene = storyboard.newScene()
|
||||
local fontSize = 14
|
||||
|
||||
local function reLoginButtonRelease(self, event)
|
||||
storyboard.gotoScene("login", "slideRight", 100)
|
||||
end
|
||||
|
||||
local function view(event)
|
||||
_G.currentBugID = event.target.id
|
||||
storyboard.gotoScene(true, "viewBug", "slideLeft", 100)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function createScreen()
|
||||
local screenGroup = display.newGroup()
|
||||
|
||||
|
||||
-- 获取myBugs
|
||||
local response = {}
|
||||
myBugAPI = myBugAPI .. "&" .. session.data.sessionName .. "=" .. session.data.sessionID
|
||||
http.request{url = myBugAPI, method = "GET", sink = ltn12.sink.table(response) } -- type(response) = table
|
||||
|
||||
if table.getn(response) == 0 then
|
||||
native.showAlert("提示", "网络错误,请查看网络或重新设置!", {"我知道了"} )
|
||||
else
|
||||
response = json.decode(table.concat(response)) --type(response) = table ,type(response.data) = string
|
||||
if crypto.digest(crypto.md5, response.data) ~= response.md5 then
|
||||
native.showAlert("提示", "数据传输不完整", {"我知道了"})
|
||||
else
|
||||
|
||||
response.data = json.decode(response.data) --type(response.data) = table, type(response.data.response) = table
|
||||
|
||||
-- tableView
|
||||
if table.getn(response.data.bugs) == 0 then
|
||||
local noBugText = display.newText("您当前没有Bug!", 10, (display.contentHeight - 35)/2, native.systemFont, fontSize)
|
||||
noBugText.xOrigin = display.contentWidth / 2
|
||||
noBugText:setTextColor(0, 0, 0)
|
||||
screenGroup:insert(noBugText)
|
||||
else
|
||||
local tableView = require("tableView")
|
||||
local myList
|
||||
local listData = {}
|
||||
for i, val in pairs(response.data.bugs) do
|
||||
listData[i] = "#" .. val.id .. " " .. val.title:sub(1,40) -- 不控制长度的话,tableView会排版错误
|
||||
|
||||
if not val.title then
|
||||
val.title = ""
|
||||
elseif not val.steps then
|
||||
val.steps = ""
|
||||
end
|
||||
|
||||
myBugs[i] = val
|
||||
end
|
||||
_G.myBugs = myBugs
|
||||
|
||||
myList = tableView.newList{
|
||||
data = listData,
|
||||
default = "listItemBg.png",
|
||||
over = "listItemBg_over.png",
|
||||
onRelease = view,
|
||||
top = topBoundary,
|
||||
bottom = bottomBoundary,
|
||||
backgroundColor = { 255, 255, 255 },
|
||||
callback = function(row)
|
||||
local t = display.newText(row, 0, 0, native.systemFont, fontSize)
|
||||
t:setTextColor(0, 0, 0)
|
||||
t.x = math.floor(t.width/2) + 12
|
||||
t.y = 30
|
||||
return t
|
||||
end
|
||||
}
|
||||
screenGroup:insert(myList)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function screenGroup:cleanUp()
|
||||
screenGroup:removeSelf()
|
||||
end
|
||||
|
||||
local navBar = display.newImage("navBar.png")
|
||||
navBar.xOrigin = display.contentWidth/2 + display.screenOriginX
|
||||
navBar.yOrigin = navBar.yOrigin + display.screenOriginY
|
||||
screenGroup:insert(navBar)
|
||||
|
||||
local reLoginButton = ui.newButton{
|
||||
default = "reLoginButton.png",
|
||||
over = "reLoginButton_over.png",
|
||||
onRelease = reLoginButtonRelease,
|
||||
text = "重新登录",
|
||||
size = 12,
|
||||
emboss = true
|
||||
}
|
||||
reLoginButton.xOrigin = display.contentWidth - reLoginButton.width/2 + display.screenOriginX
|
||||
reLoginButton.yOrigin = navBar.height/2 + display.screenOriginY
|
||||
screenGroup:insert(reLoginButton)
|
||||
|
||||
|
||||
local navHeader = display.newText("我的Bug", 0, 0, native.systemFont, 18)
|
||||
navHeader:setTextColor(255, 255, 255)
|
||||
navHeader.xOrigin = display.contentWidth/2
|
||||
navHeader.yOrigin = navBar.yOrigin
|
||||
screenGroup:insert(navHeader)
|
||||
|
||||
return screenGroup
|
||||
end
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
module(..., package.seeall)
|
||||
|
||||
-- global vars
|
||||
myTasks = {}
|
||||
currentTaskID = nil
|
||||
|
||||
-- local vars
|
||||
local scene = storyboard.newScene()
|
||||
local fontSize = 14
|
||||
|
||||
local function reLoginButtonRelease(self, event)
|
||||
storyboard.gotoScene("login", "slideRight", 100)
|
||||
end
|
||||
|
||||
local function view(event)
|
||||
_G.currentTaskID = event.target.id
|
||||
storyboard.gotoScene(true, "viewTask", "slideLeft", 100)
|
||||
return true
|
||||
end
|
||||
|
||||
function createScreen()
|
||||
local screenGroup = display.newGroup()
|
||||
|
||||
-- 获取tasks
|
||||
local response = {}
|
||||
myTaskAPI = myTaskAPI .. "&" .. session.data.sessionName .. "=" .. session.data.sessionID
|
||||
http.request{url = myTaskAPI, method = "GET", sink = ltn12.sink.table(response) } -- type(response) = table
|
||||
|
||||
if table.getn(response) == 0 then
|
||||
native.showAlert("提示", "网络错误,请查看网络或重新设置!", {"我知道了"} )
|
||||
else
|
||||
response = json.decode(table.concat(response)) --type(response) = table ,type(response.data) = string
|
||||
if crypto.digest(crypto.md5, response.data) ~= response.md5 then
|
||||
native.showAlert("提示", "数据传输不完整", {"我知道了"})
|
||||
else
|
||||
|
||||
response.data = json.decode(response.data) --type(tasks.data) = table, type(tasks.data.tasks) = table
|
||||
|
||||
-- tableView
|
||||
if table.getn(response.data.tasks) == 0 then
|
||||
local noTaskText = display.newText("您当前没有任务!" , 10, (display.contentHeight - 35)/2, native.systemFont, fontSize)
|
||||
noTaskText.xOrigin = display.contentWidth / 2
|
||||
noTaskText:setTextColor(0, 0, 0)
|
||||
screenGroup:insert(noTaskText)
|
||||
else
|
||||
local tableView = require("tableView")
|
||||
local myList
|
||||
local listData = {}
|
||||
|
||||
for i, val in pairs(response.data.tasks) do
|
||||
listData[i] = "#" .. val.id .. " " .. val.name:sub(1,40)
|
||||
|
||||
if not val.desc then
|
||||
val.desc = ""
|
||||
end
|
||||
|
||||
myTasks[i] = val
|
||||
end
|
||||
_G.myTasks = myTasks
|
||||
|
||||
myList = tableView.newList{
|
||||
data = listData, -- listData下标必须从1开始,否则出错
|
||||
default = "listItemBg.png",
|
||||
over = "listItemBg_over.png",
|
||||
onRelease = view,
|
||||
top = topBoundary,
|
||||
bottom = bottomBoundary,
|
||||
backgroundColor = { 255, 255, 255 },
|
||||
callback = function(row)
|
||||
local t = display.newText(row, 0, 0, native.systemFont, fontSize)
|
||||
t:setTextColor(0, 0, 0)
|
||||
t.x = math.floor(t.width/2) + 12
|
||||
t.y = 30
|
||||
return t
|
||||
end
|
||||
}
|
||||
screenGroup:insert(myList)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function screenGroup:cleanUp()
|
||||
screenGroup:removeSelf()
|
||||
end
|
||||
|
||||
local navBar = display.newImage("navBar.png")
|
||||
navBar.xOrigin = display.contentWidth/2 + display.screenOriginX
|
||||
navBar.yOrigin = navBar.yOrigin + display.screenOriginY
|
||||
screenGroup:insert(navBar)
|
||||
|
||||
local reLoginButton = ui.newButton{
|
||||
default = "reLoginButton.png",
|
||||
over = "reLoginButton_over.png",
|
||||
onRelease = reLoginButtonRelease,
|
||||
text = "重新登录",
|
||||
size = 12,
|
||||
emboss = true
|
||||
}
|
||||
reLoginButton.xOrigin = display.contentWidth - reLoginButton.width/2 + display.screenOriginX
|
||||
reLoginButton.yOrigin = navBar.height/2 + display.screenOriginY
|
||||
screenGroup:insert(reLoginButton)
|
||||
|
||||
local navHeader = display.newText("我的任务", 0, 0, native.systemFont, 18)
|
||||
navHeader:setTextColor(255, 255, 255)
|
||||
navHeader.xOrigin = display.contentWidth/2
|
||||
navHeader.yOrigin = navBar.yOrigin
|
||||
screenGroup:insert(navHeader)
|
||||
|
||||
return screenGroup
|
||||
end
|
||||
@@ -1,118 +0,0 @@
|
||||
module(..., package.seeall)
|
||||
|
||||
-- global vars
|
||||
myTodos = {}
|
||||
currentTodoID = nil
|
||||
|
||||
-- local vars
|
||||
local physics = require( "physics" )
|
||||
local scene = storyboard.newScene()
|
||||
local tableView = require("tableView")
|
||||
local fontSize = 14
|
||||
|
||||
local function reLoginButtonRelease(self, event)
|
||||
storyboard.gotoScene("login", "slideRight", 100)
|
||||
end
|
||||
|
||||
local function view(event)
|
||||
_G.currentTodoID = event.target.id
|
||||
storyboard.gotoScene(true, "viewTodo", "slideLeft", 100)
|
||||
return true
|
||||
end
|
||||
|
||||
-- createScreen
|
||||
function createScreen()
|
||||
local screenGroup = display.newGroup()
|
||||
|
||||
local backgroundImg = display.newImage("background.png")
|
||||
backgroundImg.xOrigin = display.contentWidth/2
|
||||
backgroundImg.yOrigin = display.contentHeight/2
|
||||
screenGroup:insert(backgroundImg)
|
||||
|
||||
-- get the todos
|
||||
local response = {}
|
||||
myTodoAPI = myTodoAPI .. "&" .. session.data.sessionName .. "=" .. session.data.sessionID
|
||||
http.request{url = myTodoAPI, method = "GET", sink = ltn12.sink.table(response) } -- type(response) = table
|
||||
|
||||
if table.getn(response) == 0 then
|
||||
native.showAlert("提示", "网络错误,请查看网络或重新设置!", {"我知道了"} )
|
||||
else
|
||||
response = json.decode(table.concat(response)) --type(response) = table ,type(response.data) = string
|
||||
if crypto.digest(crypto.md5, response.data) ~= response.md5 then
|
||||
native.showAlert("提示", "数据传输不完整", {"我知道了"})
|
||||
else
|
||||
response.data = json.decode(response.data) --type(response.data) = table, type(response.data.todos) = table
|
||||
|
||||
if table.getn(response.data.todos) == 0 then
|
||||
local noTodoText = display.newText("您当前没有Todo!", 10, (display.contentHeight - 35)/2, native.systemFontBold, fontSize)
|
||||
noTodoText.xOrigin = display.contentWidth / 2
|
||||
noTodoText:setTextColor(0, 0, 0)
|
||||
screenGroup:insert(noTodoText)
|
||||
else
|
||||
-- tableView
|
||||
local myList
|
||||
local listData = {}
|
||||
for i, val in pairs(response.data.todos) do
|
||||
listData[i] = "#" .. val.id .. " " .. val.name:sub(1,40) -- 不控制长度的话,tableView会排版错误
|
||||
|
||||
if not val.name then
|
||||
val.name = ""
|
||||
elseif not val.desc then
|
||||
val.desc = ""
|
||||
end
|
||||
|
||||
myTodos[i] = val
|
||||
end
|
||||
|
||||
_G.myTodos = myTodos
|
||||
|
||||
myList = tableView.newList{
|
||||
data = listData, -- listData下标必须从1开始,否则出错
|
||||
default = "listItemBg.png",
|
||||
over = "listItemBg_over.png",
|
||||
onRelease = view,
|
||||
top = topBoundary,
|
||||
bottom = bottomBoundary,
|
||||
backgroundColor = { 255, 255, 255 },
|
||||
callback = function(row)
|
||||
local t = display.newText(row, 0, 0, native.systemFont, 14)
|
||||
t:setTextColor(0, 0, 0)
|
||||
t.x = math.floor(t.width/2) + 12
|
||||
t.y = 30
|
||||
return t
|
||||
end
|
||||
}
|
||||
screenGroup:insert(myList)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function screenGroup:cleanUp()
|
||||
screenGroup:removeSelf()
|
||||
end
|
||||
|
||||
local navBar = display.newImage("navBar.png")
|
||||
navBar.xOrigin = display.contentWidth/2 + display.screenOriginX
|
||||
navBar.yOrigin = navBar.yOrigin + display.screenOriginY
|
||||
screenGroup:insert(navBar)
|
||||
|
||||
local reLoginButton = ui.newButton{
|
||||
default = "reLoginButton.png",
|
||||
over = "reLoginButton_over.png",
|
||||
onRelease = reLoginButtonRelease,
|
||||
text = "重新登录",
|
||||
size = 12,
|
||||
emboss = true
|
||||
}
|
||||
reLoginButton.xOrigin = display.contentWidth - reLoginButton.width/2 + display.screenOriginX
|
||||
reLoginButton.yOrigin = navBar.height/2 + display.screenOriginY
|
||||
screenGroup:insert(reLoginButton)
|
||||
|
||||
local navHeader = display.newText("我的Todo", 0, 0, native.systemFontBold, 18)
|
||||
navHeader:setTextColor(255, 255, 255)
|
||||
navHeader.xOrigin = display.contentWidth/2
|
||||
navHeader.yOrigin = navBar.yOrigin
|
||||
screenGroup:insert(navHeader)
|
||||
|
||||
return screenGroup
|
||||
end
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -1,206 +0,0 @@
|
||||
-- scrollView.lua
|
||||
--
|
||||
-- Version 1.0
|
||||
--
|
||||
-- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in the
|
||||
-- Software without restriction, including without limitation the rights to use, copy,
|
||||
-- modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
-- and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
-- following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all copies
|
||||
-- or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
-- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
-- DEALINGS IN THE SOFTWARE.
|
||||
|
||||
module(..., package.seeall)
|
||||
|
||||
-- set some global values for width and height of the screen
|
||||
local screenW, screenH = display.contentWidth, display.contentHeight
|
||||
local viewableScreenW, viewableScreenH = display.viewableContentWidth, display.viewableContentHeight
|
||||
local screenOffsetW, screenOffsetH = display.contentWidth - display.viewableContentWidth, display.contentHeight - display.viewableContentHeight
|
||||
|
||||
local prevTime = 0
|
||||
|
||||
function new(params)
|
||||
-- setup a group to be the scrolling screen
|
||||
local scrollView = display.newGroup()
|
||||
|
||||
scrollView.top = params.top or 0
|
||||
scrollView.bottom = params.bottom or 0
|
||||
|
||||
function scrollView:touch(event)
|
||||
local phase = event.phase
|
||||
print(phase)
|
||||
|
||||
if( phase == "began" ) then
|
||||
print(scrollView.y)
|
||||
self.startPos = event.y
|
||||
self.prevPos = event.y
|
||||
self.delta, self.velocity = 0, 0
|
||||
if self.tween then transition.cancel(self.tween) end
|
||||
|
||||
Runtime:removeEventListener("enterFrame", scrollView )
|
||||
|
||||
self.prevTime = 0
|
||||
self.prevY = 0
|
||||
|
||||
transition.to(self.scrollBar, { time=200, alpha=1 } )
|
||||
|
||||
-- Start tracking velocity
|
||||
Runtime:addEventListener("enterFrame", trackVelocity)
|
||||
|
||||
-- Subsequent touch events will target button even if they are outside the contentBounds of button
|
||||
display.getCurrentStage():setFocus( self )
|
||||
self.isFocus = true
|
||||
|
||||
elseif( self.isFocus ) then
|
||||
|
||||
if( phase == "moved" ) then
|
||||
local bottomLimit = screenH - self.height - self.bottom
|
||||
|
||||
self.delta = event.y - self.prevPos
|
||||
self.prevPos = event.y
|
||||
if ( self.y > self.top or self.y < bottomLimit ) then
|
||||
self.y = self.y + self.delta/2
|
||||
else
|
||||
self.y = self.y + self.delta
|
||||
end
|
||||
|
||||
scrollView:moveScrollBar()
|
||||
|
||||
elseif( phase == "ended" or phase == "cancelled" ) then
|
||||
local dragDistance = event.y - self.startPos
|
||||
self.lastTime = event.time
|
||||
|
||||
Runtime:addEventListener("enterFrame", scrollView )
|
||||
Runtime:removeEventListener("enterFrame", trackVelocity)
|
||||
|
||||
-- Allow touch events to be sent normally to the objects they "hit"
|
||||
display.getCurrentStage():setFocus( nil )
|
||||
self.isFocus = false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function scrollView:enterFrame(event)
|
||||
local friction = 0.9
|
||||
local timePassed = event.time - self.lastTime
|
||||
self.lastTime = self.lastTime + timePassed
|
||||
|
||||
--turn off scrolling if velocity is near zero
|
||||
if math.abs(self.velocity) < .01 then
|
||||
self.velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollView )
|
||||
transition.to(self.scrollBar, { time=400, alpha=0 } )
|
||||
end
|
||||
|
||||
self.velocity = self.velocity*friction
|
||||
|
||||
self.y = math.floor(self.y + self.velocity*timePassed)
|
||||
|
||||
local upperLimit = self.top
|
||||
local bottomLimit = screenH - self.height - self.bottom
|
||||
|
||||
if ( self.y > upperLimit ) then
|
||||
self.velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollView )
|
||||
self.tween = transition.to(self, { time=400, y=upperLimit, transition=easing.outQuad})
|
||||
transition.to(self.scrollBar, { time=400, alpha=0 } )
|
||||
elseif ( self.y < bottomLimit and bottomLimit < 0 ) then
|
||||
self.velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollView )
|
||||
self.tween = transition.to(self, { time=400, y=bottomLimit, transition=easing.outQuad})
|
||||
transition.to(self.scrollBar, { time=400, alpha=0 } )
|
||||
elseif ( self.y < bottomLimit ) then
|
||||
self.velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollView )
|
||||
self.tween = transition.to(self, { time=400, y=upperLimit, transition=easing.outQuad})
|
||||
transition.to(self.scrollBar, { time=400, alpha=0 } )
|
||||
end
|
||||
|
||||
scrollView:moveScrollBar()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function scrollView:moveScrollBar()
|
||||
if self.scrollBar then
|
||||
local scrollBar = self.scrollBar
|
||||
|
||||
scrollBar.y = -self.y*self.yRatio + scrollBar.height*0.5 + self.top
|
||||
|
||||
if scrollBar.y < 5 + self.top + scrollBar.height*0.5 then
|
||||
scrollBar.y = 5 + self.top + scrollBar.height*0.5
|
||||
end
|
||||
if scrollBar.y > screenH - self.bottom - 5 - scrollBar.height*0.5 then
|
||||
scrollBar.y = screenH - self.bottom - 5 - scrollBar.height*0.5
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function trackVelocity(event)
|
||||
local timePassed = event.time - scrollView.prevTime
|
||||
scrollView.prevTime = scrollView.prevTime + timePassed
|
||||
|
||||
if scrollView.prevY then
|
||||
scrollView.velocity = (scrollView.y - scrollView.prevY)/timePassed
|
||||
end
|
||||
scrollView.prevY = scrollView.y
|
||||
end
|
||||
|
||||
scrollView.y = scrollView.top
|
||||
|
||||
-- setup the touch listener
|
||||
scrollView:addEventListener( "touch", scrollView )
|
||||
|
||||
function scrollView:addScrollBar(r,g,b,a)
|
||||
if self.scrollBar then self.scrollBar:removeSelf() end
|
||||
|
||||
local scrollColorR = r or 0
|
||||
local scrollColorG = g or 0
|
||||
local scrollColorB = b or 0
|
||||
local scrollColorA = a or 120
|
||||
|
||||
local viewPortH = screenH - self.top - self.bottom
|
||||
local scrollH = viewPortH*self.height/(self.height*2 - viewPortH)
|
||||
local scrollBar = display.newRoundedRect(viewableScreenW-8,0,5,scrollH,2)
|
||||
scrollBar:setFillColor(scrollColorR, scrollColorG, scrollColorB, scrollColorA)
|
||||
|
||||
local yRatio = scrollH/self.height
|
||||
self.yRatio = yRatio
|
||||
|
||||
scrollBar.y = scrollBar.height*0.5 + self.top
|
||||
|
||||
self.scrollBar = scrollBar
|
||||
|
||||
transition.to(scrollBar, { time=400, alpha=0 } )
|
||||
end
|
||||
|
||||
function scrollView:removeScrollBar()
|
||||
if self.scrollBar then
|
||||
self.scrollBar:removeSelf()
|
||||
self.scrollBar = nil
|
||||
end
|
||||
end
|
||||
|
||||
function scrollView:cleanUp()
|
||||
Runtime:removeEventListener("enterFrame", trackVelocity)
|
||||
Runtime:removeEventListener( "touch", scrollView )
|
||||
Runtime:removeEventListener("enterFrame", scrollView )
|
||||
scrollView:removeScrollBar()
|
||||
end
|
||||
|
||||
return scrollView
|
||||
end
|
||||
@@ -1,149 +0,0 @@
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
-- zentao vars
|
||||
local allConfigs = {} -- read all configs from config.json
|
||||
local currentName = ""
|
||||
local currentUrl = "http://"
|
||||
|
||||
-- page elements
|
||||
local backgroundImg
|
||||
local nameField, urlField
|
||||
local savaButton, resetButton, backButton
|
||||
|
||||
local function fieldHandler( event )
|
||||
if ( "began" == event.phase ) then
|
||||
-- This is the "keyboard has appeared" event
|
||||
-- In some cases you may want to adjust the interface when the keyboard appears.
|
||||
elseif ( "ended" == event.phase ) then
|
||||
|
||||
-- This event is called when the user stops editing a field: for example, when they touch a different field
|
||||
elseif ( "submitted" == event.phase ) then
|
||||
-- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard
|
||||
-- Hide keyboard
|
||||
native.setKeyboardFocus( nil )
|
||||
end
|
||||
end
|
||||
|
||||
local function saveButtonRelease( self, event )
|
||||
|
||||
if string.len(nameField.text) > 0 and string.len(urlField.text) > 0 then
|
||||
currentName = nameField.text
|
||||
if string.find(urlField.text, "http://") then
|
||||
currentUrl = urlField.text
|
||||
else
|
||||
currentUrl = currentUrl .. urlField.text .. '/'
|
||||
end
|
||||
|
||||
local userData = json.encode({name = currentName, url = currentUrl})
|
||||
local path = system.pathForFile( "config.txt", system.DocumentsDirectory )
|
||||
local file = io.open(path, "w+")
|
||||
local result = file:write(userData)
|
||||
if result then
|
||||
native.showAlert("提示", "保存成功", { "OK" })
|
||||
end
|
||||
io.close( file )
|
||||
else
|
||||
native.showAlert("提示", "请正确填写!", { "OK" })
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function backButtonRelease( self, event )
|
||||
storyboard.gotoScene(true, "login", "slideRight", 200)
|
||||
end
|
||||
|
||||
|
||||
function scene:createScene( event )
|
||||
local screenGroup = self.view
|
||||
|
||||
backgroundImg = display.newImage("background.png")
|
||||
backgroundImg.xOrigin = display.contentWidth/2 + display.screenOriginX
|
||||
backgroundImg.yOrigin = display.contentHeight/2 + display.screenOriginY
|
||||
screenGroup:insert(backgroundImg)
|
||||
|
||||
end
|
||||
|
||||
function scene:enterScene( event )
|
||||
storyboard.purgeScene("login")
|
||||
|
||||
local screenGroup = self.view
|
||||
|
||||
screenGroup:insert(navBar)
|
||||
screenGroup:insert(navHeader)
|
||||
|
||||
-- newText
|
||||
nameText = display.newText("名称:", display.contentWidth/6, display.contentHeight / 3, native.systemFontBold, 18)
|
||||
nameText:setTextColor(0,0,0)
|
||||
screenGroup:insert(nameText)
|
||||
|
||||
urlText = display.newText(" " .. " Url:", display.contentWidth/6, display.contentHeight*13/ 30 , native.systemFontBold, 18)
|
||||
urlText:setTextColor(0,0,0)
|
||||
screenGroup:insert(urlText)
|
||||
|
||||
-- newTextField
|
||||
nameField = native.newTextField(display.contentWidth/6 + nameText.width + 10, display.contentHeight / 3, display.contentWidth/2, 40)
|
||||
nameField.text = currentName
|
||||
screenGroup:insert(nameField)
|
||||
|
||||
urlField = native.newTextField(display.contentWidth/6 + urlText.width + 10, display.contentHeight *13/30, display.contentWidth/2, 40)
|
||||
urlField.text = currentUrl
|
||||
urlField.inputType = "url"
|
||||
screenGroup:insert(urlField)
|
||||
|
||||
-- Button
|
||||
saveButton = ui.newButton{
|
||||
default = "button.png",
|
||||
over = "button_over.png",
|
||||
onRelease = saveButtonRelease,
|
||||
size = 24,
|
||||
text = "保存",
|
||||
emboss = true
|
||||
}
|
||||
saveButton.xOrigin = display.contentWidth/4
|
||||
saveButton.yOrigin = display.contentHeight*3/4
|
||||
local tmpWidth = saveButton.width
|
||||
saveButton.width = math.floor(display.contentWidth/3)
|
||||
saveButton.height = math.floor(saveButton.width * saveButton.height / tmpWidth)
|
||||
screenGroup:insert(saveButton)
|
||||
|
||||
resetButton = ui.newButton{
|
||||
default = "button.png",
|
||||
over = "button_over.png",
|
||||
onRelease = resetButtonRelease,
|
||||
size = 24,
|
||||
text = "重置",
|
||||
emboss = true
|
||||
}
|
||||
resetButton.xOrigin = display.contentWidth*3/4
|
||||
resetButton.yOrigin = display.contentHeight*3/4
|
||||
tmpWidth = resetButton.width
|
||||
resetButton.width = display.contentWidth/3
|
||||
resetButton.height = math.floor(resetButton.width * resetButton.height / tmpWidth)
|
||||
screenGroup:insert(resetButton)
|
||||
|
||||
backButton = ui.newButton{
|
||||
default = "backButton.png",
|
||||
over = "backButton_over.png",
|
||||
onRelease = backButtonRelease,
|
||||
size = 16,
|
||||
emboss = true
|
||||
}
|
||||
backButton.xOrigin = display.contentWidth - backButton.width/2 + display.screenOriginX
|
||||
backButton.yOrigin = display.contentHeight - backButton.height/2 - display.screenOriginY
|
||||
screenGroup:insert(backButton)
|
||||
|
||||
end
|
||||
|
||||
function scene:exitScene()
|
||||
end
|
||||
|
||||
function scene:destroyScene(event)
|
||||
end
|
||||
|
||||
scene:addEventListener("createScene", scene)
|
||||
scene:addEventListener("enterScene", scene)
|
||||
scene:addEventListener("exitScene", scene)
|
||||
scene:addEventListener("destroyScene", scene)
|
||||
|
||||
return scene
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1,420 +0,0 @@
|
||||
-- tableView.lua, Table View Library
|
||||
--
|
||||
-- Version 1.3
|
||||
--
|
||||
-- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in the
|
||||
-- Software without restriction, including without limitation the rights to use, copy,
|
||||
-- modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
-- and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
-- following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all copies
|
||||
-- or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
-- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
-- DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
module(..., package.seeall)
|
||||
|
||||
--properties
|
||||
local screenW, screenH = display.contentWidth, display.contentHeight
|
||||
local viewableScreenW, viewableScreenH = display.viewableContentWidth, display.viewableContentHeight
|
||||
local screenOffsetW, screenOffsetH = display.contentWidth - display.viewableContentWidth, display.contentHeight - display.viewableContentHeight
|
||||
|
||||
local currentTarget, detailScreen, velocity, currentDefault, currentOver, prevY
|
||||
local startTime, lastTime, prevTime = 0, 0, 0
|
||||
|
||||
--methods
|
||||
|
||||
function showHighlight(event)
|
||||
local timePassed = system.getTimer() - startTime
|
||||
|
||||
if timePassed > 100 then
|
||||
print("highlight")
|
||||
currentDefault.isVisible = false
|
||||
currentOver.isVisible = true
|
||||
Runtime:removeEventListener( "enterFrame", showHighlight )
|
||||
end
|
||||
end
|
||||
|
||||
function newListItemHandler(self, event)
|
||||
local t = currentTarget --could use self.target.parent possibly
|
||||
local phase = event.phase
|
||||
print("touch: ".. phase)
|
||||
|
||||
local default = self.default
|
||||
local over = self.over
|
||||
local top = self.top
|
||||
local bottom = self.bottom
|
||||
local upperLimit, bottomLimit = top, screenH - currentTarget.height - bottom
|
||||
|
||||
local result = true
|
||||
|
||||
if( phase == "began" ) then
|
||||
-- Subsequent touch events will target button even if they are outside the contentBounds of button
|
||||
display.getCurrentStage():setFocus( self )
|
||||
self.isFocus = true
|
||||
|
||||
startPos = event.y
|
||||
prevPos = event.y
|
||||
delta, velocity = 0, 0
|
||||
if currentTarget.tween then transition.cancel(currentTarget.tween) end
|
||||
|
||||
Runtime:removeEventListener("enterFrame", scrollList )
|
||||
Runtime:addEventListener("enterFrame", moveCat)
|
||||
|
||||
-- Start tracking velocity
|
||||
Runtime:addEventListener("enterFrame", trackVelocity)
|
||||
|
||||
if over then
|
||||
currentDefault = default
|
||||
currentOver = over
|
||||
startTime = system.getTimer()
|
||||
Runtime:addEventListener( "enterFrame", showHighlight )
|
||||
end
|
||||
|
||||
elseif( self.isFocus ) then
|
||||
|
||||
if( phase == "moved" ) then
|
||||
|
||||
Runtime:removeEventListener( "enterFrame", showHighlight )
|
||||
if over then
|
||||
default.isVisible = true
|
||||
over.isVisible = false
|
||||
end
|
||||
|
||||
delta = event.y - prevPos
|
||||
prevPos = event.y
|
||||
if ( t.y > upperLimit or t.y < bottomLimit ) then
|
||||
t.y = t.y + delta/2
|
||||
else
|
||||
t.y = t.y + delta
|
||||
end
|
||||
|
||||
elseif( phase == "ended" or phase == "cancelled" ) then
|
||||
|
||||
lastTime = event.time
|
||||
|
||||
local dragDistance = event.y - startPos
|
||||
--velocity = delta
|
||||
Runtime:removeEventListener("enterFrame", moveCat)
|
||||
Runtime:removeEventListener("enterFrame", trackVelocity)
|
||||
Runtime:addEventListener("enterFrame", scrollList )
|
||||
|
||||
local bounds = self.contentBounds
|
||||
local x, y = event.x, event.y
|
||||
local isWithinBounds = bounds.xMin <= x and bounds.xMax >= x and bounds.yMin <= y and bounds.yMax >= y
|
||||
|
||||
-- Only consider this a "click", if the user lifts their finger inside button's contentBounds
|
||||
if isWithinBounds and (dragDistance < 10 and dragDistance > -10 ) then
|
||||
velocity = 0
|
||||
result = self.onRelease(event)
|
||||
end
|
||||
|
||||
-- Allow touch events to be sent normally to the objects they "hit"
|
||||
display.getCurrentStage():setFocus( nil )
|
||||
self.isFocus = false
|
||||
|
||||
if over then
|
||||
default.isVisible = true
|
||||
over.isVisible = false
|
||||
Runtime:removeEventListener( "enterFrame", showHighlight )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function newListItem(params)
|
||||
local data = params.data
|
||||
local default = params.default
|
||||
local over = params.over
|
||||
local onRelease = params.onRelease
|
||||
local top = params.top
|
||||
local bottom = params.bottom
|
||||
local callback = params.callback
|
||||
local id = params.id
|
||||
|
||||
local thisItem = display.newGroup()
|
||||
|
||||
if params.default then
|
||||
default = display.newImage( params.default )
|
||||
thisItem:insert( default )
|
||||
default.x = default.width*.5 - screenOffsetW
|
||||
thisItem.default = default
|
||||
end
|
||||
|
||||
if params.over then
|
||||
over = display.newImage( params.over )
|
||||
over.isVisible = false
|
||||
thisItem:insert( over )
|
||||
over.x = over.width*.5 - screenOffsetW
|
||||
thisItem.over = over
|
||||
end
|
||||
|
||||
thisItem.id = id
|
||||
thisItem.data = data
|
||||
thisItem.onRelease = onRelease
|
||||
thisItem.top = top
|
||||
thisItem.bottom = bottom
|
||||
|
||||
local t = callback(data)
|
||||
thisItem:insert( t )
|
||||
|
||||
thisItem.touch = newListItemHandler
|
||||
thisItem:addEventListener( "touch", thisItem )
|
||||
|
||||
return thisItem
|
||||
end
|
||||
|
||||
function newList(params)
|
||||
local textSize = 16
|
||||
local data = params.data
|
||||
local default = params.default
|
||||
local over = params.over
|
||||
local onRelease = params.onRelease
|
||||
local top = params.top or 20
|
||||
local bottom = params.bottom or 48
|
||||
local cat = params.cat
|
||||
local order = params.order or {}
|
||||
local categoryBackground = params.categoryBackground
|
||||
local backgroundColor = params.backgroundColor
|
||||
local callback = params.callback or function(item)
|
||||
local t = display.newText(item, 0, 0, native.systemFontBold, textSize)
|
||||
t:setTextColor(255, 255, 255)
|
||||
t.x = math.floor(t.width/2) + 20
|
||||
t.y = 24
|
||||
return t
|
||||
end
|
||||
|
||||
--setup the list view
|
||||
local listView = display.newGroup()
|
||||
local prevY, prevH = 0, 0
|
||||
|
||||
|
||||
if cat then
|
||||
local catTable = {}
|
||||
|
||||
--get the implicit categories
|
||||
local prevCat = 0
|
||||
for i=1, #data do
|
||||
if data[i][cat] ~= prevCat then
|
||||
table.insert(catTable, data[i][cat])
|
||||
prevCat = data[i][cat]
|
||||
end
|
||||
end
|
||||
|
||||
if order then
|
||||
--clean up the user provided order table by removing any empty categories
|
||||
local n = 1
|
||||
while n < #order do
|
||||
if not in_table(order[n], catTable) then
|
||||
table.remove(order, n)
|
||||
else
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
|
||||
--add any categories not specified to the user order of categories
|
||||
for i=1, #catTable do
|
||||
if not in_table(catTable[i], order) then
|
||||
table.insert(order, catTable[i])
|
||||
end
|
||||
end
|
||||
else
|
||||
order = catTable
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local j = 1
|
||||
local c = {}
|
||||
local offset = 12
|
||||
while true do
|
||||
local h = order[j]
|
||||
|
||||
if h then
|
||||
local g = display.newGroup()
|
||||
local b
|
||||
if categoryBackground then
|
||||
b = display.newImage(categoryBackground, true)
|
||||
else
|
||||
b = display.newRect(0, 0, screenW, textSize*1.5)
|
||||
b:setFillColor(0, 0, 0, 100)
|
||||
end
|
||||
g:insert( b )
|
||||
|
||||
local labelShadow = display.newText( h, 0, 0, native.systemFontBold, textSize )
|
||||
labelShadow:setTextColor( 0, 0, 0, 128 )
|
||||
g:insert( labelShadow, true )
|
||||
labelShadow.x = labelShadow.width*.5 + 1 + offset + screenOffsetW*.5
|
||||
labelShadow.y = textSize*.8 + 1
|
||||
|
||||
local t = display.newText(h, 0, 0, native.systemFontBold, textSize)
|
||||
t:setTextColor(255, 255, 255)
|
||||
g:insert( t )
|
||||
t.x = t.width*.5 + offset + screenOffsetW*.5
|
||||
t.y = textSize*.8
|
||||
|
||||
listView:insert( g )
|
||||
g.x = 0
|
||||
g.y = prevY + prevH
|
||||
prevY = g.y
|
||||
prevH = g.height
|
||||
table.insert(c, g)
|
||||
c[#c].yInit = g.y
|
||||
end
|
||||
|
||||
--iterate over the data and add items to the list view
|
||||
for i=1, #data do
|
||||
if data[i][cat] == h then
|
||||
local thisItem = newListItem{
|
||||
data = data[i],
|
||||
default = default,
|
||||
over = over,
|
||||
onRelease = onRelease,
|
||||
top = top,
|
||||
bottom = bottom,
|
||||
callback = callback,
|
||||
id = i
|
||||
}
|
||||
|
||||
listView:insert( 1, thisItem )
|
||||
|
||||
thisItem.x = 0 + screenOffsetW*.5
|
||||
thisItem.y = prevY + prevH
|
||||
|
||||
--save the Y and height
|
||||
prevY = thisItem.y
|
||||
prevH = thisItem.height
|
||||
end --if
|
||||
end --for
|
||||
|
||||
j = j + 1
|
||||
|
||||
if not order[j] then break end
|
||||
end --while
|
||||
|
||||
if backgroundColor then
|
||||
local bgColor = display.newRect(0, 0, screenW, screenH)
|
||||
bgColor:setFillColor(backgroundColor[1], backgroundColor[2], backgroundColor[3])
|
||||
bgColor.width = listView.width
|
||||
bgColor.height = listView.height
|
||||
bgColor.y = bgColor.height*.5
|
||||
listView:insert(1, bgColor)
|
||||
end
|
||||
|
||||
listView.y = top
|
||||
listView.top = top
|
||||
listView.bottom = bottom
|
||||
listView.c = c
|
||||
|
||||
currentTarget = listView
|
||||
|
||||
function listView:cleanUp()
|
||||
print("tableView cleanUp")
|
||||
Runtime:removeEventListener("enterFrame", moveCat )
|
||||
Runtime:removeEventListener("enterFrame", scrollList )
|
||||
Runtime:removeEventListener( "enterFrame", showHighlight )
|
||||
Runtime:removeEventListener("enterFrame", trackVelocity)
|
||||
local i
|
||||
for i = listView.numChildren, 1, -1 do
|
||||
--test
|
||||
listView[i]:removeEventListener("touch", newListItemHandler)
|
||||
listView:remove(i)
|
||||
listView[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return listView
|
||||
end
|
||||
|
||||
function scrollList(event)
|
||||
local friction = 0.9
|
||||
local timePassed = event.time - lastTime
|
||||
lastTime = lastTime + timePassed
|
||||
|
||||
--turn off scrolling if velocity is near zero
|
||||
if math.abs(velocity) < .01 then
|
||||
velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollList )
|
||||
end
|
||||
|
||||
velocity = velocity*friction
|
||||
|
||||
currentTarget.y = math.floor(currentTarget.y + velocity*timePassed)
|
||||
|
||||
moveCat()
|
||||
|
||||
local upperLimit = currentTarget.top
|
||||
local bottomLimit = screenH - currentTarget.height - currentTarget.bottom
|
||||
|
||||
if ( currentTarget.y > upperLimit ) then
|
||||
velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollList )
|
||||
Runtime:addEventListener("enterFrame", moveCat )
|
||||
currentTarget.tween = transition.to(currentTarget, { time=400, y=upperLimit, transition=easing.outQuad})
|
||||
elseif ( currentTarget.y < bottomLimit and bottomLimit < 0 ) then
|
||||
velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollList )
|
||||
Runtime:addEventListener("enterFrame", moveCat )
|
||||
currentTarget.tween = transition.to(currentTarget, { time=400, y=bottomLimit, transition=easing.outQuad})
|
||||
elseif ( currentTarget.y < bottomLimit ) then
|
||||
velocity = 0
|
||||
Runtime:removeEventListener("enterFrame", scrollList )
|
||||
Runtime:addEventListener("enterFrame", moveCat )
|
||||
currentTarget.tween = transition.to(currentTarget, { time=400, y=upperLimit, transition=easing.outQuad})
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function moveCat()
|
||||
local upperLimit = currentTarget.top
|
||||
|
||||
for i=1, #currentTarget.c do
|
||||
if( currentTarget.y > upperLimit - currentTarget.c[i].yInit ) then
|
||||
currentTarget.c[i].y = currentTarget.c[i].yInit
|
||||
end
|
||||
|
||||
if ( currentTarget.y < upperLimit - currentTarget.c[i].yInit ) then
|
||||
currentTarget.c[i].y = upperLimit - currentTarget.y
|
||||
end
|
||||
|
||||
if( i > 1 ) then
|
||||
if ( currentTarget.c[i].y < currentTarget.c[i-1].y + currentTarget.c[i].height ) then
|
||||
currentTarget.c[i-1].y = currentTarget.c[i].y - currentTarget.c[i].height
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function trackVelocity(event)
|
||||
local timePassed = event.time - prevTime
|
||||
prevTime = prevTime + timePassed
|
||||
|
||||
if prevY then
|
||||
velocity = (currentTarget.y - prevY)/timePassed
|
||||
end
|
||||
prevY = currentTarget.y
|
||||
end
|
||||
|
||||
--look for an item in a table
|
||||
function in_table ( e, t )
|
||||
for _,v in pairs(t) do
|
||||
if (v==e) then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
-- ui.lua (currently includes Button class with labels, font selection and optional event model)
|
||||
|
||||
-- Version 1.5 (works with multitouch, adds setText() method to buttons)
|
||||
--
|
||||
-- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in the
|
||||
-- Software without restriction, including without limitation the rights to use, copy,
|
||||
-- modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
-- and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
-- following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all copies
|
||||
-- or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
-- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
-- DEALINGS IN THE SOFTWARE.
|
||||
|
||||
module(..., package.seeall)
|
||||
|
||||
-----------------
|
||||
-- Helper function for newButton utility function below
|
||||
local function newButtonHandler( self, event )
|
||||
|
||||
local result = true
|
||||
|
||||
local default = self[1]
|
||||
local over = self[2]
|
||||
|
||||
-- General "onEvent" function overrides onPress and onRelease, if present
|
||||
local onEvent = self._onEvent
|
||||
|
||||
local onPress = self._onPress
|
||||
local onRelease = self._onRelease
|
||||
|
||||
local buttonEvent = {}
|
||||
if (self._id) then
|
||||
buttonEvent.id = self._id
|
||||
end
|
||||
|
||||
local phase = event.phase
|
||||
if "began" == phase then
|
||||
if over then
|
||||
default.isVisible = false
|
||||
over.isVisible = true
|
||||
end
|
||||
|
||||
if onEvent then
|
||||
buttonEvent.phase = "press"
|
||||
result = onEvent( buttonEvent )
|
||||
elseif onPress then
|
||||
result = onPress( event )
|
||||
end
|
||||
|
||||
-- Subsequent touch events will target button even if they are outside the contentBounds of button
|
||||
display.getCurrentStage():setFocus( self, event.id )
|
||||
self.isFocus = true
|
||||
|
||||
elseif self.isFocus then
|
||||
local bounds = self.contentBounds
|
||||
local x,y = event.x,event.y
|
||||
local isWithinBounds =
|
||||
bounds.xMin <= x and bounds.xMax >= x and bounds.yMin <= y and bounds.yMax >= y
|
||||
|
||||
if "moved" == phase then
|
||||
if over then
|
||||
-- The rollover image should only be visible while the finger is within button's contentBounds
|
||||
default.isVisible = not isWithinBounds
|
||||
over.isVisible = isWithinBounds
|
||||
end
|
||||
|
||||
elseif "ended" == phase or "cancelled" == phase then
|
||||
if over then
|
||||
default.isVisible = true
|
||||
over.isVisible = false
|
||||
end
|
||||
|
||||
if "ended" == phase then
|
||||
-- Only consider this a "click" if the user lifts their finger inside button's contentBounds
|
||||
if isWithinBounds then
|
||||
if onEvent then
|
||||
buttonEvent.phase = "release"
|
||||
result = onEvent( buttonEvent )
|
||||
elseif onRelease then
|
||||
result = onRelease( event )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Allow touch events to be sent normally to the objects they "hit"
|
||||
display.getCurrentStage():setFocus( self, nil )
|
||||
self.isFocus = false
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
---------------
|
||||
-- Button class
|
||||
|
||||
function newButton( params )
|
||||
local button, default, over, size, font, textColor, offset
|
||||
|
||||
if params.default then
|
||||
button = display.newGroup()
|
||||
default = display.newImage( params.default )
|
||||
button:insert( default, true )
|
||||
end
|
||||
|
||||
if params.over then
|
||||
over = display.newImage( params.over )
|
||||
over.isVisible = false
|
||||
button:insert( over, true )
|
||||
end
|
||||
|
||||
-- Public methods
|
||||
function button:setText( newText )
|
||||
|
||||
local labelText = self.text
|
||||
if ( labelText ) then
|
||||
labelText:removeSelf()
|
||||
self.text = nil
|
||||
end
|
||||
|
||||
local labelShadow = self.shadow
|
||||
if ( labelShadow ) then
|
||||
labelShadow:removeSelf()
|
||||
self.shadow = nil
|
||||
end
|
||||
|
||||
local labelHighlight = self.highlight
|
||||
if ( labelHighlight ) then
|
||||
labelHighlight:removeSelf()
|
||||
self.highlight = nil
|
||||
end
|
||||
|
||||
if ( params.size and type(params.size) == "number" ) then size=params.size else size=20 end
|
||||
if ( params.font ) then font=params.font else font=native.systemFontBold end
|
||||
if ( params.textColor ) then textColor=params.textColor else textColor={ 255, 255, 255, 255 } end
|
||||
|
||||
-- Optional vertical correction for fonts with unusual baselines (I'm looking at you, Zapfino)
|
||||
if ( params.offset and type(params.offset) == "number" ) then offset=params.offset else offset = 0 end
|
||||
|
||||
if ( params.emboss ) then
|
||||
-- Make the label text look "embossed" (also adjusts effect for textColor brightness)
|
||||
local textBrightness = ( textColor[1] + textColor[2] + textColor[3] ) / 3
|
||||
|
||||
labelHighlight = display.newText( newText, 0, 0, font, size )
|
||||
if ( textBrightness > 127) then
|
||||
labelHighlight:setTextColor( 255, 255, 255, 20 )
|
||||
else
|
||||
labelHighlight:setTextColor( 255, 255, 255, 140 )
|
||||
end
|
||||
button:insert( labelHighlight, true )
|
||||
labelHighlight.x = labelHighlight.x + 1.5; labelHighlight.y = labelHighlight.y + 1.5 + offset
|
||||
self.highlight = labelHighlight
|
||||
|
||||
labelShadow = display.newText( newText, 0, 0, font, size )
|
||||
if ( textBrightness > 127) then
|
||||
labelShadow:setTextColor( 0, 0, 0, 128 )
|
||||
else
|
||||
labelShadow:setTextColor( 0, 0, 0, 20 )
|
||||
end
|
||||
button:insert( labelShadow, true )
|
||||
labelShadow.x = labelShadow.x - 1; labelShadow.y = labelShadow.y - 1 + offset
|
||||
self.shadow = labelShadow
|
||||
end
|
||||
|
||||
labelText = display.newText( newText, 0, 0, font, size )
|
||||
labelText:setTextColor( textColor[1], textColor[2], textColor[3], textColor[4] )
|
||||
button:insert( labelText, true )
|
||||
labelText.y = labelText.y + offset
|
||||
self.text = labelText
|
||||
end
|
||||
|
||||
if params.text then
|
||||
button:setText( params.text )
|
||||
end
|
||||
|
||||
if ( params.onPress and ( type(params.onPress) == "function" ) ) then
|
||||
button._onPress = params.onPress
|
||||
end
|
||||
if ( params.onRelease and ( type(params.onRelease) == "function" ) ) then
|
||||
button._onRelease = params.onRelease
|
||||
end
|
||||
|
||||
if (params.onEvent and ( type(params.onEvent) == "function" ) ) then
|
||||
button._onEvent = params.onEvent
|
||||
end
|
||||
|
||||
-- Set button as a table listener by setting a table method and adding the button as its own table listener for "touch" events
|
||||
button.touch = newButtonHandler
|
||||
button:addEventListener( "touch", button )
|
||||
|
||||
if params.x then
|
||||
button.x = params.x
|
||||
end
|
||||
|
||||
if params.y then
|
||||
button.y = params.y
|
||||
end
|
||||
|
||||
if params.id then
|
||||
button._id = params.id
|
||||
end
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
|
||||
--------------
|
||||
-- Label class
|
||||
|
||||
function newLabel( params )
|
||||
local labelText
|
||||
local size, font, textColor, align
|
||||
local t = display.newGroup()
|
||||
|
||||
if ( params.bounds ) then
|
||||
local bounds = params.bounds
|
||||
local left = bounds[1]
|
||||
local top = bounds[2]
|
||||
local width = bounds[3]
|
||||
local height = bounds[4]
|
||||
|
||||
if ( params.size and type(params.size) == "number" ) then size=params.size else size=20 end
|
||||
if ( params.font ) then font=params.font else font=native.systemFontBold end
|
||||
if ( params.textColor ) then textColor=params.textColor else textColor={ 255, 255, 255, 255 } end
|
||||
if ( params.offset and type(params.offset) == "number" ) then offset=params.offset else offset = 0 end
|
||||
if ( params.align ) then align = params.align else align = "center" end
|
||||
|
||||
if ( params.text ) then
|
||||
labelText = display.newText( params.text, 0, 0, font, size )
|
||||
labelText:setTextColor( textColor[1], textColor[2], textColor[3], textColor[4] )
|
||||
t:insert( labelText )
|
||||
-- TODO: handle no-initial-text case by creating a field with an empty string?
|
||||
|
||||
if ( align == "left" ) then
|
||||
labelText.x = left + labelText.contentWidth * 0.5
|
||||
elseif ( align == "right" ) then
|
||||
labelText.x = (left + width) - labelText.contentWidth * 0.5
|
||||
else
|
||||
labelText.x = ((2 * left) + width) * 0.5
|
||||
end
|
||||
end
|
||||
|
||||
labelText.y = top + labelText.contentHeight * 0.5
|
||||
|
||||
-- Public methods
|
||||
function t:setText( newText )
|
||||
if ( newText ) then
|
||||
labelText.text = newText
|
||||
|
||||
if ( "left" == align ) then
|
||||
labelText.x = left + labelText.contentWidth / 2
|
||||
elseif ( "right" == align ) then
|
||||
labelText.x = (left + width) - labelText.contentWidth / 2
|
||||
else
|
||||
labelText.x = ((2 * left) + width) / 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function t:setTextColor( r, g, b, a )
|
||||
local newR = 255
|
||||
local newG = 255
|
||||
local newB = 255
|
||||
local newA = 255
|
||||
|
||||
if ( r and type(r) == "number" ) then newR = r end
|
||||
if ( g and type(g) == "number" ) then newG = g end
|
||||
if ( b and type(b) == "number" ) then newB = b end
|
||||
if ( a and type(a) == "number" ) then newA = a end
|
||||
|
||||
labelText:setTextColor( r, g, b, a )
|
||||
end
|
||||
end
|
||||
|
||||
-- Return instance (as display group)
|
||||
return t
|
||||
|
||||
end
|
||||
@@ -1,33 +0,0 @@
|
||||
local function chsize(char)
|
||||
if not char then
|
||||
return 0
|
||||
elseif char > 240 then
|
||||
return 4
|
||||
elseif char > 225 then
|
||||
return 3
|
||||
elseif char > 192 then
|
||||
return 2
|
||||
else
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function utf8sub(str, startChar, numChars)
|
||||
local startIndex = 1
|
||||
while startChar > 1 do
|
||||
local char = string.byte(str, startIndex)
|
||||
startIndex = startIndex + chsize(char)
|
||||
startChar = startChar - 1
|
||||
end
|
||||
|
||||
local currentIndex = startIndex
|
||||
|
||||
while numChars > 0 and currentIndex <= #str do
|
||||
local char = string.byte(str, currentIndex)
|
||||
currentIndex = currentIndex + chsize(char)
|
||||
numChars = numChars -1
|
||||
end
|
||||
return str:sub(startIndex, currentIndex - 1)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,321 +0,0 @@
|
||||
-- util.lua
|
||||
--
|
||||
-- Version 1.0
|
||||
--
|
||||
-- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in the
|
||||
-- Software without restriction, including without limitation the rights to use, copy,
|
||||
-- modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
-- and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
-- following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all copies
|
||||
-- or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
-- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
-- DEALINGS IN THE SOFTWARE.
|
||||
|
||||
module(..., package.seeall)
|
||||
|
||||
-- set some global values for width and height of the screen
|
||||
local screenW, screenH = display.contentWidth, display.contentHeight
|
||||
local viewableScreenW, viewableScreenH = display.viewableContentWidth, display.viewableContentHeight
|
||||
local screenOffsetW, screenOffsetH = display.contentWidth - display.viewableContentWidth, display.contentHeight - display.viewableContentHeight
|
||||
|
||||
--------------------------------------------
|
||||
-- Wrap text
|
||||
function wrap(str, limit, indent, indent1)
|
||||
indent = indent or ""
|
||||
indent1 = indent1 or indent
|
||||
limit = limit or 72
|
||||
local here = 1-#indent1
|
||||
return indent1..str:gsub("(%s+)()(%S+)()",
|
||||
function(sp, st, word, fi)
|
||||
if fi-here > limit then
|
||||
here = st - #indent
|
||||
return "\n"..indent..word
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function explode(div,str)
|
||||
if (div=='') then return false end
|
||||
local pos,arr = 0,{}
|
||||
-- for each divider found
|
||||
for st,sp in function() return string.find(str,div,pos,true) end do
|
||||
table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider
|
||||
pos = sp + 1 -- Jump past current divider
|
||||
end
|
||||
table.insert(arr,string.sub(str,pos)) -- Attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
|
||||
function wrappedText(str, limit, size, font, color, indent, indent1)
|
||||
str = explode("\n", str)
|
||||
size = tonumber(size) or 12
|
||||
color = color or {255, 255, 255}
|
||||
font = font or "Helvetica"
|
||||
|
||||
--apply line breaks using the wrapping function
|
||||
local i = 1
|
||||
local strFinal = ""
|
||||
while i <= #str do
|
||||
strW = wrap(str[i], limit, indent, indent1)
|
||||
strFinal = strFinal.."\n"..strW
|
||||
i = i + 1
|
||||
end
|
||||
str = strFinal
|
||||
|
||||
--search for each line that ends with a line break and add to an array
|
||||
local pos, arr = 0, {}
|
||||
for st,sp in function() return string.find(str,"\n",pos,true) end do
|
||||
table.insert(arr,string.sub(str,pos,st-1))
|
||||
pos = sp + 1
|
||||
end
|
||||
table.insert(arr,string.sub(str,pos))
|
||||
|
||||
--iterate through the array and add each item as a display object to the group
|
||||
local g = display.newGroup()
|
||||
local i = 1
|
||||
while i <= #arr do
|
||||
local t = display.newText( arr[i], 0, 0, font, size )
|
||||
t:setTextColor( color[1], color[2], color[3] )
|
||||
t.x = math.floor(t.width/2)
|
||||
t.y = math.floor((size*1.3)*(i-1))
|
||||
g:insert(t)
|
||||
i = i + 1
|
||||
end
|
||||
return g
|
||||
end
|
||||
|
||||
--[[
|
||||
|
||||
-- USAGE:
|
||||
local myText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc euismod justo sapien, at sollicitudin lacus. Quisque vestibulum commodo felis id posuere."
|
||||
local myTextObject = wrappedText(myText, 46)
|
||||
--local myTextObject = wrappedText(myText, 46, 16)
|
||||
--local myTextObject = wrappedText(myText, 46, 16, {255, 0, 0})
|
||||
local myGroup = display.newGroup()
|
||||
myGroup:insert( myTextObject )
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
--------------------------------------------
|
||||
-- XML Parser
|
||||
function parseargs(s)
|
||||
local arg = {}
|
||||
string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
|
||||
arg[w] = a
|
||||
end)
|
||||
return arg
|
||||
end
|
||||
|
||||
function collect(s)
|
||||
local stack = {}
|
||||
local top = {}
|
||||
table.insert(stack, top)
|
||||
local ni,c,label,xarg, empty
|
||||
local i, j = 1, 1
|
||||
while true do
|
||||
ni,j,c,label,xarg, empty = string.find(s, "<(%/?)([%w:]+)(.-)(%/?)>", i)
|
||||
if not ni then break end
|
||||
local text = string.sub(s, i, ni-1)
|
||||
if not string.find(text, "^%s*$") then
|
||||
table.insert(top, text)
|
||||
end
|
||||
if empty == "/" then -- empty element tag
|
||||
table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
|
||||
elseif c == "" then -- start tag
|
||||
top = {label=label, xarg=parseargs(xarg)}
|
||||
table.insert(stack, top) -- new level
|
||||
else -- end tag
|
||||
local toclose = table.remove(stack) -- remove top
|
||||
top = stack[#stack]
|
||||
if #stack < 1 then
|
||||
error("nothing to close with "..label)
|
||||
end
|
||||
if toclose.label ~= label then
|
||||
error("trying to close "..toclose.label.." with "..label)
|
||||
end
|
||||
table.insert(top, toclose)
|
||||
end
|
||||
i = j+1
|
||||
end
|
||||
local text = string.sub(s, i)
|
||||
if not string.find(text, "^%s*$") then
|
||||
table.insert(stack[#stack], text)
|
||||
end
|
||||
if #stack > 1 then
|
||||
error("unclosed "..stack[stack.n].label)
|
||||
end
|
||||
return stack[1]
|
||||
end
|
||||
|
||||
------------------------------
|
||||
|
||||
function aLink(e)
|
||||
local t = e.target
|
||||
if (t.link) then
|
||||
print(e.target.link)
|
||||
system.openURL( e.target.link )
|
||||
else
|
||||
print("no link found")
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------
|
||||
-- Helper function for newLink utility function below
|
||||
local function newLinkHandler( self, event )
|
||||
local result = true
|
||||
local default = self[1]
|
||||
local over = self[2]
|
||||
local t = self.parent
|
||||
local phase = event.phase
|
||||
print ("newButtonHandler: "..phase)
|
||||
|
||||
if over then
|
||||
linkCurrentDefault = default
|
||||
linkCurrentRollover = over
|
||||
end
|
||||
|
||||
local function showHighlight (event)
|
||||
local timePassed = event.time - startTime
|
||||
print("timePassed: "..timePassed)
|
||||
|
||||
if timePassed > 100 then
|
||||
print("highlight")
|
||||
linkCurrentDefault.isVisible = false
|
||||
linkCurrentRollover.isVisible = true
|
||||
Runtime:removeEventListener( "enterFrame", showHighlight )
|
||||
end
|
||||
end
|
||||
|
||||
if "began" == phase then
|
||||
t.startPos = event.y
|
||||
t.prevPos = event.y
|
||||
t.delta, t.velocity = 0, 0
|
||||
if t.tween then transition.cancel(t.tween) end
|
||||
Runtime:removeEventListener("enterFrame", t )
|
||||
|
||||
self.prevTime = 0
|
||||
self.prevY = 0
|
||||
|
||||
if over then
|
||||
startTime = event.time
|
||||
Runtime:addEventListener( "enterFrame", showHighlight )
|
||||
end
|
||||
|
||||
local onPress = self._onPress
|
||||
if onPress then
|
||||
result = onPress( event )
|
||||
end
|
||||
|
||||
-- Subsequent touch events will target button even if they are outside the contentBounds of button
|
||||
display.getCurrentStage():setFocus( self )
|
||||
self.isFocus = true
|
||||
|
||||
elseif self.isFocus then
|
||||
|
||||
if "moved" == phase then
|
||||
local bottomLimit = screenH - t.height - t.bottom
|
||||
|
||||
t.delta = event.y - t.prevPos
|
||||
t.prevPos = event.y
|
||||
if ( t.y > t.top or t.y < bottomLimit ) then
|
||||
t.y = t.y + t.delta/2
|
||||
else
|
||||
t.y = t.y + t.delta
|
||||
end
|
||||
|
||||
--Track velocity while the user is moving the view
|
||||
local timePassed = event.time - t.prevTime
|
||||
t.prevTime = t.prevTime + timePassed
|
||||
if t.prevY then
|
||||
t.velocity = (t.y - t.prevY)/timePassed
|
||||
end
|
||||
t.prevY = t.y
|
||||
|
||||
if over then
|
||||
Runtime:removeEventListener( "enterFrame", showHighlight )
|
||||
-- the over image should only be visible while the finger is within button's contentBounds
|
||||
default.isVisible = true --not isWithinBounds
|
||||
over.isVisible = false --isWithinBounds
|
||||
end
|
||||
elseif "ended" == phase or "cancelled" == phase then
|
||||
local dragDistance = event.y - t.startPos
|
||||
t.lastTime = event.time
|
||||
|
||||
Runtime:addEventListener("enterFrame", t )
|
||||
|
||||
local bounds = self.contentBounds
|
||||
local x,y = event.x,event.y
|
||||
local isWithinBounds =
|
||||
bounds.xMin <= x and bounds.xMax >= x and bounds.yMin <= y and bounds.yMax >= y
|
||||
|
||||
if over then
|
||||
Runtime:removeEventListener( "enterFrame", showHighlight )
|
||||
default.isVisible = true
|
||||
over.isVisible = false
|
||||
end
|
||||
|
||||
-- Only consider this a "click", if the user lifts their finger inside button's contentBounds
|
||||
if isWithinBounds and (dragDistance < 10 and dragDistance > -10 ) then
|
||||
result = self._onRelease( event )
|
||||
end
|
||||
|
||||
-- Allow touch events to be sent normally to the objects they "hit"
|
||||
display.getCurrentStage():setFocus( nil )
|
||||
self.isFocus = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
function newLink( params )
|
||||
local button
|
||||
|
||||
if params.default and params.onRelease then
|
||||
button = display.newGroup()
|
||||
local default = display.newImage( params.default )
|
||||
button:insert( default, true )
|
||||
|
||||
if params.over then
|
||||
local over = display.newImage( params.over )
|
||||
over.isVisible = false
|
||||
button:insert( over, true )
|
||||
end
|
||||
|
||||
if type( params.onPress ) == "function" then
|
||||
button._onPress = params.onPress
|
||||
end
|
||||
if type( params.onRelease ) == "function" then
|
||||
button._onRelease = params.onRelease
|
||||
end
|
||||
|
||||
button.buttonID = params.buttonID
|
||||
|
||||
-- Set button as a table listener by setting a table method and adding the button as its own table listener for "touch" events
|
||||
button.touch = newLinkHandler
|
||||
button:addEventListener( "touch", button )
|
||||
end
|
||||
|
||||
if params.x then
|
||||
button.x = params.x
|
||||
end
|
||||
if params.y then
|
||||
button.y = params.y
|
||||
end
|
||||
|
||||
return button
|
||||
end
|
||||
@@ -1,92 +0,0 @@
|
||||
require("htmltotext")
|
||||
require("utf8sub")
|
||||
|
||||
local storyboard = require "storyboard"
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
local function backButtonRelease( self, event )
|
||||
storyboard.gotoScene("index", "slideRight", 100)
|
||||
end
|
||||
|
||||
-- 第一创建的时候才把代码放在这里,以后重新进入就不会调用createScene了
|
||||
-- 所以逻辑代码应该放到enterScene中
|
||||
function scene:createScene(event)
|
||||
local screenGroup = self.view
|
||||
|
||||
local backgroundImg = display.newImage("background.png")
|
||||
backgroundImg.xOrigin = display.contentWidth/2
|
||||
backgroundImg.yOrigin = display.contentHeight/2
|
||||
screenGroup:insert(backgroundImg)
|
||||
end
|
||||
|
||||
function scene:enterScene( event )
|
||||
local screenGroup = self.view
|
||||
|
||||
display.setStatusBar( display.HiddenStatusBar )
|
||||
|
||||
--import the scrolling classes
|
||||
local scrollView = require("scrollView")
|
||||
|
||||
-- Setup a scrollable content group
|
||||
local scrollView = scrollView.new{ top=display.screenOriginY, bottom=display.screenOriginY }
|
||||
screenGroup:insert(scrollView)
|
||||
|
||||
local fontSize = 18
|
||||
local textHeight = fontSize+10
|
||||
local startX = 10
|
||||
local startY = 10
|
||||
local lineLimit = math.floor(display.contentWidth / fontSize)
|
||||
local output = ""
|
||||
local i = 0
|
||||
|
||||
-- display bug title
|
||||
local title = "#" .. myBugs[currentBugID].id .. " " .. myBugs[currentBugID].title
|
||||
while string.len(output) < string.len(title) do
|
||||
output = output .. utf8sub(title, i*lineLimit+1, lineLimit) .. "\n"
|
||||
i = i+1
|
||||
end
|
||||
local titleText = display.newText(output, startX, startY, system.defaultFontBold, fontSize)
|
||||
titleText:setTextColor(0, 0, 0)
|
||||
scrollView:insert(titleText)
|
||||
startY = startY + (i-1)*textHeight
|
||||
|
||||
-- display bug basic information
|
||||
output = ""
|
||||
i = 0
|
||||
local steps = "步骤:" .. HTML_ToText(myBugs[currentBugID].steps)
|
||||
local steps = string.gsub(steps, "\n", "")
|
||||
while string.len(output) < string.len(steps) do
|
||||
output = output .. utf8sub(steps, i*lineLimit+1, lineLimit) .. "\n"
|
||||
i = i+1
|
||||
end
|
||||
local stepsText = display.newText(output, startX, startY + 2*textHeight, system.defaultFont, 14)
|
||||
stepsText:setTextColor(0, 0, 0)
|
||||
scrollView:insert(stepsText)
|
||||
|
||||
backButton = ui.newButton{
|
||||
default = "backButton.png",
|
||||
over = "backButton_over.png",
|
||||
onRelease = backButtonRelease,
|
||||
size = 16,
|
||||
emboss = true
|
||||
}
|
||||
backButton.xOrigin = display.contentWidth - backButton.width/2
|
||||
backButton.yOrigin = display.contentHeight - backButton.height/2 - display.screenOriginY
|
||||
screenGroup:insert(backButton)
|
||||
|
||||
scrollView:addScrollBar()
|
||||
|
||||
end
|
||||
|
||||
function scene:exitScene( event )
|
||||
end
|
||||
|
||||
function scene:destroyScene( event )
|
||||
end
|
||||
|
||||
scene:addEventListener("createScene", scene )
|
||||
scene:addEventListener("enterScene", scene )
|
||||
scene:addEventListener("exitScene", scene )
|
||||
scene:addEventListener("destroyScene", scene )
|
||||
|
||||
return scene
|
||||
@@ -1,110 +0,0 @@
|
||||
-- viewController.lua, View Controller Library
|
||||
--
|
||||
-- Version 1.0, currently supports tabs
|
||||
--
|
||||
-- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in the
|
||||
-- Software without restriction, including without limitation the rights to use, copy,
|
||||
-- modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
-- and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
-- following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all copies
|
||||
-- or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
-- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
-- DEALINGS IN THE SOFTWARE.
|
||||
|
||||
module(..., package.seeall)
|
||||
|
||||
--initial values
|
||||
local screenW, screenH = display.contentWidth, display.contentHeight
|
||||
local viewableScreenW, viewableScreenH = display.viewableContentWidth, display.viewableContentHeight
|
||||
local screenOffsetW, screenOffsetH = display.contentWidth - display.viewableContentWidth, display.contentHeight - display.viewableContentHeight
|
||||
|
||||
function newTabBar(params)
|
||||
local background = params.background
|
||||
local tabs = params.tabs
|
||||
local default = params.default
|
||||
local over = params.over
|
||||
local onRelease = params.onRelease
|
||||
|
||||
local tabBar = display.newGroup()
|
||||
|
||||
if background then
|
||||
local tabBG = display.newImage("tabBar.png")
|
||||
tabBar:insert(tabBG)
|
||||
end
|
||||
|
||||
--check for tab and tab over images specified by the user
|
||||
if not default then
|
||||
--if no tab images, use tab1.png, tab2.png, etc.
|
||||
default = {}
|
||||
for i=1, #tabs do
|
||||
table.insert(default, "tab".. i ..".png")
|
||||
end
|
||||
end
|
||||
if not over then
|
||||
--if no tab over images, use tab1_over.png, tab2_over.png, etc.
|
||||
over = {}
|
||||
for i=1, #tabs do
|
||||
table.insert(over, "tab".. i .."_over.png")
|
||||
end
|
||||
end
|
||||
|
||||
tabBar.y = math.floor(screenH - tabBar.height - display.screenOriginY)
|
||||
tabBar.x = 0
|
||||
|
||||
--create the tabs
|
||||
for i=1, #tabs do
|
||||
local tab = ui.newButton{
|
||||
default = default[i],
|
||||
over = over[i],
|
||||
onRelease = onRelease,
|
||||
text = tabs[i],
|
||||
textColor = {0, 0, 0, 165},
|
||||
font = "Helvetica",
|
||||
size = 14,
|
||||
}
|
||||
tabBar:insert(tab)
|
||||
|
||||
local numberOfTabs = #tabs
|
||||
local tabButtonWidth = tab.width
|
||||
local totalButtonWidth = tabButtonWidth * numberOfTabs
|
||||
local tabSpacing = (screenW - totalButtonWidth)/(numberOfTabs+1)
|
||||
|
||||
tab.x = tab.width*(i-1) + tabSpacing * i + tab.width*0.5
|
||||
tab.y = tab.height*0.5
|
||||
|
||||
tab.id = i
|
||||
end
|
||||
|
||||
tabBar.selected = function(target)
|
||||
if not target then target = tabBar[2] end
|
||||
if tabBar.highlight then tabBar:remove(tabBar.highlight) end
|
||||
|
||||
local highlight = ui.newButton{
|
||||
default = over[target.id],
|
||||
over = default[target.id],
|
||||
onRelease = onRelease,
|
||||
text = tabs[target.id],
|
||||
font = "Helvetica",
|
||||
size = 14,
|
||||
}
|
||||
highlight.id = target.id
|
||||
tabBar:insert(highlight)
|
||||
|
||||
highlight.x = target.x
|
||||
highlight.y = target.y
|
||||
|
||||
tabBar.highlight = highlight
|
||||
end
|
||||
|
||||
return tabBar
|
||||
end
|
||||
@@ -1,87 +0,0 @@
|
||||
require("htmltotext")
|
||||
require("utf8sub")
|
||||
|
||||
local storyboard = require "storyboard"
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
local function backButtonRelease( self, event )
|
||||
storyboard.gotoScene("index", "slideRight", 100)
|
||||
end
|
||||
|
||||
function scene:createScene(event)
|
||||
local screenGroup = self.view
|
||||
|
||||
local backgroundImg = display.newImage("view_background.png")
|
||||
backgroundImg.xOrigin = display.contentWidth/2
|
||||
backgroundImg.yOrigin = display.contentHeight/2
|
||||
screenGroup:insert(backgroundImg)
|
||||
end
|
||||
|
||||
function scene:enterScene( event )
|
||||
local screenGroup = self.view
|
||||
|
||||
--import the scrolling classes
|
||||
local scrollView = require("scrollView")
|
||||
|
||||
-- Setup a scrollable content group
|
||||
local scrollView = scrollView.new{top=display.screenOriginY, bottom=display.screenOriginY}
|
||||
screenGroup:insert(scrollView)
|
||||
|
||||
local fontSize = 18
|
||||
local textHeight = fontSize+10
|
||||
local startX = 10
|
||||
local startY = 10
|
||||
local lineLimit = math.floor(display.contentWidth / fontSize)
|
||||
local output = ""
|
||||
local i = 0
|
||||
|
||||
-- display task name
|
||||
local name = "#" .. myTasks[currentTaskID].id .. " " .. myTasks[currentTaskID].name
|
||||
while string.len(output) < string.len(name) do
|
||||
output = output .. utf8sub(name, i*lineLimit+1, lineLimit) .. "\n"
|
||||
i = i+1
|
||||
end
|
||||
local nameText = display.newText(output, startX, startY, system.defaultFontBold, fontSize)
|
||||
nameText:setTextColor(0, 0, 0)
|
||||
scrollView:insert(nameText)
|
||||
startY = startY + (i-1)*textHeight
|
||||
|
||||
output = ""
|
||||
i = 0
|
||||
local desc = HTML_ToText(myTasks[currentTaskID].desc)
|
||||
local desc = string.gsub(desc, "\n", "")
|
||||
while string.len(output) < string.len(desc) do
|
||||
output = output .. utf8sub(desc, i*lineLimit+1, lineLimit) .. "\n"
|
||||
i = i+1
|
||||
end
|
||||
local descText = display.newText(output, startX, startY + textHeight, system.defaultFont, 14)
|
||||
descText:setTextColor(0, 0, 0)
|
||||
scrollView:insert(descText)
|
||||
startY = startY + (i-1)*textHeight
|
||||
|
||||
backButton = ui.newButton{
|
||||
default = "backButton.png",
|
||||
over = "backButton_over.png",
|
||||
onRelease = backButtonRelease,
|
||||
size = 16,
|
||||
emboss = true
|
||||
}
|
||||
backButton.xOrigin = display.contentWidth - backButton.width/2
|
||||
backButton.yOrigin = display.contentHeight - backButton.height/2 - display.screenOriginY
|
||||
screenGroup:insert(backButton)
|
||||
|
||||
scrollView:addScrollBar()
|
||||
end
|
||||
|
||||
function scene:exitScene( event )
|
||||
end
|
||||
|
||||
function scene:destroyScene( event )
|
||||
end
|
||||
|
||||
scene:addEventListener("createScene", scene )
|
||||
scene:addEventListener("enterScene", scene )
|
||||
scene:addEventListener("exitScene", scene )
|
||||
scene:addEventListener("destroyScene", scene )
|
||||
|
||||
return scene
|
||||
@@ -1,91 +0,0 @@
|
||||
require("htmltotext")
|
||||
require("utf8sub")
|
||||
local storyboard = require "storyboard"
|
||||
local scene = storyboard.newScene()
|
||||
|
||||
local function backButtonRelease( self, event )
|
||||
storyboard.gotoScene("index", "slideRight", 100)
|
||||
end
|
||||
|
||||
function scene:createScene(event)
|
||||
local screenGroup = self.view
|
||||
|
||||
local backgroundImg = display.newImage("view_background.png")
|
||||
backgroundImg.xOrigin = display.contentWidth/2
|
||||
backgroundImg.yOrigin = display.contentHeight/2
|
||||
screenGroup:insert(backgroundImg)
|
||||
|
||||
end
|
||||
|
||||
function scene:enterScene( event )
|
||||
local screenGroup = self.view
|
||||
|
||||
display.setStatusBar( display.HiddenStatusBar )
|
||||
|
||||
--import the scrolling classes
|
||||
local scrollView = require("scrollView")
|
||||
|
||||
-- Setup a scrollable content group
|
||||
local scrollView = scrollView.new{ top=display.screenOriginY, bottom=display.screenOriginY }
|
||||
screenGroup:insert(scrollView)
|
||||
|
||||
local fontSize = 18
|
||||
local textHeight = fontSize+10
|
||||
local startX = 10
|
||||
local startY = 10
|
||||
local lineLimit = math.floor(display.contentWidth / fontSize)
|
||||
local output = ""
|
||||
local i = 0
|
||||
|
||||
-- display todo name
|
||||
local name = "#" .. myTodos[currentTodoID].id .. " " .. myTodos[currentTodoID].name
|
||||
while string.len(output) < string.len(name) do
|
||||
output = output .. utf8sub(name, i*lineLimit+1, lineLimit) .. "\n"
|
||||
i = i+1
|
||||
end
|
||||
local nameText = display.newText(output, startX, startY, system.defaultFontBold, fontSize)
|
||||
nameText:setTextColor(0, 0, 0)
|
||||
startY = startY + (i-1)*textHeight
|
||||
scrollView:insert(nameText)
|
||||
|
||||
-- desc text
|
||||
output = ""
|
||||
i = 0
|
||||
local desc = HTML_ToText(myTodos[currentTodoID].desc)
|
||||
local desc = string.gsub(desc, "\n", "")
|
||||
while string.len(output) < string.len(desc) do
|
||||
output = output .. utf8sub(desc, i*lineLimit+1, lineLimit) .. "\n"
|
||||
i = i+1
|
||||
end
|
||||
|
||||
local descText = display.newText(output, startX, startY + textHeight, system.defaultFont, 14)
|
||||
descText:setTextColor(0, 0, 0)
|
||||
scrollView:insert(descText)
|
||||
|
||||
backButton = ui.newButton{
|
||||
default = "backButton.png",
|
||||
over = "backButton_over.png",
|
||||
onRelease = backButtonRelease,
|
||||
size = 16,
|
||||
emboss = true
|
||||
}
|
||||
backButton.xOrigin = display.contentWidth - backButton.width/2
|
||||
backButton.yOrigin = display.contentHeight - backButton.height/2 - display.screenOriginY
|
||||
screenGroup:insert(backButton)
|
||||
|
||||
scrollView:addScrollBar()
|
||||
|
||||
end
|
||||
|
||||
function scene:exitScene( event )
|
||||
end
|
||||
|
||||
function scene:destroyScene( event )
|
||||
end
|
||||
|
||||
scene:addEventListener("createScene", scene )
|
||||
scene:addEventListener("enterScene", scene )
|
||||
scene:addEventListener("exitScene", scene )
|
||||
scene:addEventListener("destroyScene", scene )
|
||||
|
||||
return scene
|
||||
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 122 KiB |