├── .gitignore ├── ConvertCSD.lua ├── README.md ├── ccext ├── LuaResHelper.lua ├── XmlParser.lua └── csd2lua.lua └── main.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Lua sources 2 | luac.out 3 | 4 | # luarocks build files 5 | *.src.rock 6 | *.zip 7 | *.tar.gz 8 | 9 | # Object files 10 | *.o 11 | *.os 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | *.def 26 | *.exp 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | 42 | -------------------------------------------------------------------------------- /ConvertCSD.lua: -------------------------------------------------------------------------------- 1 | cc.FileUtils:getInstance():addSearchPath("cocosstudio/") 2 | 3 | local _M = {} 4 | 5 | local _CSDFILES = { 6 | "Start/StartScene.csd", 7 | "Dialog/Dialog.csd", 8 | "Lobby/LobbyScene.csd", 9 | "Game/GameScene.csd", 10 | 11 | "Test/TestScene.csd", 12 | "Test/TestLayer.csd", 13 | } 14 | 15 | function _M.doConvert() 16 | local fileUtils = cc.FileUtils:getInstance() 17 | 18 | for _, v in pairs(_CSDFILES) do 19 | local csdFile = fileUtils:fullPathForFilename(string.format("cocosstudio/%s", v)) 20 | local luaFile = fileUtils:fullPathForFilename("res") .. "/" .. string.gsub(v, ".csd", ".lua") 21 | 22 | if not csdFile or csdFile == "" then 23 | print("\n") 24 | print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") 25 | error("Not found: " .. "cocosstudio/" .. v) 26 | break 27 | end 28 | 29 | print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") 30 | print("【.csd】: " .. string.format("cocosstudio/%s", v)) 31 | print("【.lua】: " .. string.format("res/%s", v)) 32 | 33 | require("ccext.csd2lua").new():csd2lua(csdFile, luaFile) 34 | 35 | print("\n\n") 36 | end 37 | end 38 | 39 | return _M 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # csd2lua 2 | 3 | 一个将 Cocos Studio 2.* 工程文件 .csd 转换成 .lua 资源的小工具,暂时仅支持 Cocos Studio “对象”面板上除了“声音”外的静态对象导出。另外,主要目的是支持“自定义控件”导出。 4 | 5 | 6 | 7 | 8 | 基本用法: 9 | 10 | require("ccext.csd2lua").new():csd2lua("FullPathName.csd", "Save_FullPathName.lua") 11 | 12 | 13 | 14 | 15 | 使用方式: 16 | 17 | 1、是基于 Cocos2d-x Lua 的项目工程(在 Cocos2d-x 3.6/Cocos Studio 2.2.5/6 上测试过) 18 | 19 | 2、把本工具的 ccext 目录拷贝进项目 src 目录 20 | 21 | 3、先用 Cocos Studio 执行一次导出,以便图片资源啊已经完整导出到对应目录下 22 | 23 | 4、参考例子 ConvertCSD.lua 和 main.lua。 24 | 25 | 自己修改 ConvertCSD.lua 里的文件列表 _CSDFILES = { "**.csd", "**.csd" },拷贝此文件进你项目 26 | 把本 main.lua 里那句 require("ConvertCSD").doConvert() 拷贝到你真正的 main.lua 27 | 28 | 5、要转换的时候,开启执行那句 require("ConvertCSD").doConvert(),否则注释掉即可 29 | 30 | 31 | 32 | 33 | 工具特点: 34 | 35 | 1、尽量去冗余化,比如 setFlippX(false)、setScaleX(1) 这些凡是跟默认参数值相同的,不必要导出的,就不导出此参数 36 | 37 | 2、精简和压缩所导出的 LUA 语句行数。测试范例是 Cocos Studio 2.2.1 导出为 8600 多行,本工具导出为 1300 行 38 | 39 | 3、你还可以改造代码,实现自定义控件导出 40 | 41 | 比如参考里面的 RichTextEx 部分,凡是“用户数据”(UserData)字段是 @class_YYYY 格式的,将以自定义 YYYY 控件导出。 42 | 比如一个 ccui.Text 是以 ccui.Text:create() 导出,但如果“用户数据”内容是 @class_RichTextEx,将以 require("ccext.RichTextEx"):create() 导出 43 | 44 | 4、本工程所有用到的图片资源以 _M.textures = { ... } 方式列出,以方便制作 loading 界面,因为载入时速度影响最大的是资源读取 45 | 46 | -------------------------------------------------------------------------------- /ccext/LuaResHelper.lua: -------------------------------------------------------------------------------- 1 | --///////////////////////////////////////////////////////////////////////////// 2 | -- LuaResHelper for csd2lua 3 | -- https://github.com/liangX-cn/csd2lua 4 | -- 5 | --///////////////////////////////////////////////////////////////////////////// 6 | 7 | local _L = {} 8 | 9 | --///////////////////////////////////////////////////////////////////////////// 10 | 11 | --///////////////////////////////////////////////////////////////////////////// 12 | function _L.setValue(obj, name, tag, size, position, ancpoint, color, opacity, zOrder, ignoreSize) 13 | if type(obj.setCascadeColorEnabled) == "function" then obj:setCascadeColorEnabled(true) end 14 | if type(obj.setCascadeOpacityEnabled) == "function" then obj:setCascadeOpacityEnabled(true) end 15 | if type(obj.setLayoutComponentEnabled) == "function" then obj:setLayoutComponentEnabled(true) end 16 | if nil ~= name then obj:setName(name) end 17 | if nil ~= tag then obj:setTag(tag) end 18 | if nil ~= color then obj:setColor(color) end 19 | if nil ~= opacity then obj:setOpacity(opacity) end 20 | if nil ~= zOrder then obj:setLocalZOrder(zOrder) end 21 | if nil ~= position then obj:setPosition(position) end 22 | if nil ~= ancpoint then obj:setAnchorPoint(ancpoint) end 23 | if nil ~= ignoreSize and type(obj.ignoreContentAdaptWithSize) == "function" then 24 | obj:ignoreContentAdaptWithSize(ignoreSize) 25 | end 26 | if nil ~= size then 27 | if type(obj.setContentSize) == "function" then 28 | obj:setContentSize(size) 29 | elseif type(obj.setSize) == "function" then 30 | obj:setSize(size) 31 | end 32 | end 33 | return _L 34 | end 35 | 36 | --///////////////////////////////////////////////////////////////////////////// 37 | function _L.setBgImage(obj, imgName, imgType, scale9En, capInsets) 38 | if nil ~= bgType then obj:setBackGroundImage(imgName, imgType or 0) end 39 | if nil ~= scale9En and type(obj.setBackGroundImageScale9Enabled) == "function" then 40 | obj:setBackGroundImageScale9Enabled(scale9En) 41 | end 42 | if nil ~= capInsets and type(obj.setBackGroundImageCapInsets) == "function" 43 | then obj:setBackGroundImageCapInsets(capInsets) 44 | end 45 | return _L 46 | end 47 | 48 | --///////////////////////////////////////////////////////////////////////////// 49 | function _L.setBgColor(obj, bgType, bgOpacity, bgColor, startColor, endColor, colorVec) 50 | if nil ~= bgType then obj:setBackGroundColorType(bgType) end 51 | if nil ~= bgOpacity then obj:setBackGroundColorOpacity(bgOpacity) end 52 | if nil ~= startColor and nil ~= endColor then obj:setBackGroundColor(startColor, endColor) end 53 | if nil ~= bgColor then obj:setBackGroundColor(bgColor) end 54 | if nil ~= colorVec then obj:setBackGroundColorVector(colorVec) end 55 | return _L 56 | end 57 | 58 | --///////////////////////////////////////////////////////////////////////////// 59 | function _L.setClickEvent(obj, cb, evt) 60 | if nil ~= cb then obj:addClickEventListener(cb("", obj, evt)) end 61 | return _L 62 | end 63 | 64 | --///////////////////////////////////////////////////////////////////////////// 65 | function _L.setTouchEvent(obj, cb, evt) 66 | if nil ~= cb then obj:addTouchEventListener(cb("", obj, evt)) end 67 | return _L 68 | end 69 | 70 | --///////////////////////////////////////////////////////////////////////////// 71 | function _L.bind(obj) 72 | _L.lay = ccui.LayoutComponent:bindLayoutComponent(obj) 73 | return _L 74 | end 75 | 76 | --///////////////////////////////////////////////////////////////////////////// 77 | function _L.setMargin(left, top, right, bottom) 78 | if nil ~= left then _L.lay:setLeftMargin(left) end 79 | if nil ~= top then _L.lay:setTopMargin(top) end 80 | if nil ~= right then _L.lay:setRightMargin(right) end 81 | if nil ~= bottom then _L.lay:setBottomMargin(bottom) end 82 | return _L 83 | end 84 | 85 | --///////////////////////////////////////////////////////////////////////////// 86 | function _L.setSize(width, height, wEnabled, hEnabled) 87 | if nil ~= width then _L.lay:setPercentWidth(width) end 88 | if nil ~= height then _L.lay:setPercentHeight(height) end 89 | if nil ~= wEnabled then _L.lay:setPercentWidthEnabled(wEnabled) end 90 | if nil ~= hEnabled then _L.lay:setPercentHeightEnabled(hEnabled) end 91 | return _L 92 | end 93 | 94 | --///////////////////////////////////////////////////////////////////////////// 95 | function _L.setPosition(x, y, xEnabled, yEnabled) 96 | if nil ~= x then _L.lay:setPositionPercentX(x) end 97 | if nil ~= y then _L.lay:setPositionPercentY(y) end 98 | if nil ~= xEnabled then _L.lay:setPositionPercentXEnabled(xEnabled) end 99 | if nil ~= yEnabled then _L.lay:setPositionPercentYEnabled(yEnabled) end 100 | return _L 101 | end 102 | 103 | --///////////////////////////////////////////////////////////////////////////// 104 | function _L.setStretch(wEnabled, hEnabled) 105 | if nil ~= wEnabled then _L.lay:setStretchWidthEnable(wEnabled) end 106 | if nil ~= hEnabled then _L.lay:setStretchHeightEnable(hEnabled) end 107 | return _L 108 | end 109 | 110 | --///////////////////////////////////////////////////////////////////////////// 111 | function _L.setEdge(hEdge, vEdge) 112 | if nil ~= hEdge then _L.lay:setHorizontalEdge(hEdge) end 113 | if nil ~= vEdge then _L.lay:setVerticalEdge(vEdge) end 114 | return _L 115 | end 116 | 117 | --///////////////////////////////////////////////////////////////////////////// 118 | 119 | return _L 120 | -------------------------------------------------------------------------------- /ccext/XmlParser.lua: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------- 2 | --------------------------------------------------------------------------------- 3 | -- 4 | -- xml.lua - XML parser for use with the Corona SDK. 5 | -- 6 | -- version: 1.2 7 | -- 8 | -- CHANGELOG: 9 | -- 10 | -- 1.2 - Created new structure for returned table 11 | -- 1.1 - Fixed base directory issue with the loadFile() function. 12 | -- 13 | -- NOTE: This is a modified version of Alexander Makeev's Lua-only XML parser 14 | -- found here: http://lua-users.org/wiki/LuaXml 15 | -- 16 | --------------------------------------------------------------------------------- 17 | --------------------------------------------------------------------------------- 18 | 19 | local _M = {} 20 | 21 | function _M.newParser() 22 | 23 | local XmlParser = {}; 24 | 25 | function XmlParser:ToXmlString(value) 26 | value = string.gsub(value, "&", "&"); -- '&' -> "&" 27 | value = string.gsub(value, "<", "<"); -- '<' -> "<" 28 | value = string.gsub(value, ">", ">"); -- '>' -> ">" 29 | value = string.gsub(value, "\"", """); -- '"' -> """ 30 | value = string.gsub(value, "([^%w%&%;%p%\t% ])", function(c) 31 | return string.format("&#x%X;", string.byte(c)) 32 | end); 33 | return value; 34 | end 35 | 36 | function XmlParser:FromXmlString(value) 37 | value = string.gsub(value, "&#x([%x]+)%;", function(h) 38 | return string.char(tonumber(h, 16)) 39 | end); 40 | value = string.gsub(value, "&#([0-9]+)%;", function(h) 41 | return string.char(tonumber(h, 10)) 42 | end); 43 | value = string.gsub(value, """, "\""); 44 | value = string.gsub(value, "'", "'"); 45 | value = string.gsub(value, ">", ">"); 46 | value = string.gsub(value, "<", "<"); 47 | value = string.gsub(value, "&", "&"); 48 | return value; 49 | end 50 | 51 | function XmlParser:ParseArgs(node, s) 52 | string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a) 53 | --print("@@@@@@@@@@@@ " .. tostring(w) .. "=" .. tostring(a)) 54 | node:addProperty(w, self:FromXmlString(a)) 55 | end) 56 | end 57 | 58 | function XmlParser:ParseNode(s) 59 | local ni, j, label, xarg, empty = string.find(s, "^([%w_:]+)(.-)(%/?)$") 60 | local lNode = _M.newNode(label) 61 | self:ParseArgs(lNode, xarg) 62 | return empty, lNode 63 | end 64 | 65 | function XmlParser:ParseXmlText(xmlText) 66 | local i, j, k = 1, 1, 1 67 | local nodes = {} 68 | local top = _M.newNode() 69 | table.insert(nodes, top) 70 | while true do 71 | j, k = string.find(xmlText, "<", i) 72 | if not j then break end 73 | 74 | local text = string.sub(xmlText, i, j - 1); 75 | if not string.find(text, "^%s*$") then 76 | local lVal = (top:value() or "") .. self:FromXmlString(text) 77 | nodes[#nodes]:setValue(lVal) 78 | i = j 79 | end 80 | 81 | local x = string.sub(xmlText, k+1, k+1) 82 | if (x == "?") then 83 | j, k = string.find(xmlText, "%?>", i) 84 | j = j + 1 85 | elseif (x == "!") then 86 | local cdataStart = string.sub(xmlText, k+2, k+8) 87 | if (cdataStart == "[CDATA[") then 88 | j, k = string.find(xmlText, "]]>", i) 89 | local cdataText = string.sub(xmlText, i+9, j-1) 90 | top:setValue((top:value() or "")..cdataText) 91 | j = j + 2 92 | else 93 | error("should be ", i) 98 | local value = string.sub(xmlText, i, j-1) 99 | local toclose = table.remove(nodes) 100 | 101 | top = nodes[#nodes] 102 | if #nodes < 1 then 103 | error("XmlParser: nothing to close with " .. value) 104 | end 105 | if toclose:name() ~= value then 106 | error("XmlParser: trying to close " .. toclose:name() .. " with " .. value) 107 | end 108 | top:addChild(toclose) 109 | else 110 | i = j + 1 111 | j, k = string.find(xmlText, ">", i) 112 | local name = string.sub(xmlText, i, j-1) 113 | local empty, lNode = self:ParseNode(name) 114 | if (empty == "/") then 115 | top:addChild(lNode) 116 | else 117 | table.insert(nodes, lNode) 118 | top = lNode 119 | end 120 | end 121 | i = j + 1 122 | end 123 | local text = string.sub(xmlText, i); 124 | if #nodes > 1 then 125 | error("XmlParser: unclosed " .. nodes[#nodes]:name()) 126 | end 127 | return top 128 | end 129 | 130 | function XmlParser:loadFile(xmlFilename) 131 | local path = cc.FileUtils:getInstance():fullPathForFilename(xmlFilename) 132 | local hFile, err = io.open(path, "r"); 133 | 134 | if hFile and not err then 135 | local xmlText = hFile:read("*a"); -- read file content 136 | io.close(hFile); 137 | return self:ParseXmlText(xmlText), nil; 138 | else 139 | print(err) 140 | return nil 141 | end 142 | end 143 | 144 | return XmlParser 145 | end 146 | 147 | function _M.newNode(name) 148 | local node = {} 149 | node.___value = nil 150 | node.___name = name 151 | node.___children = {} 152 | node.___props = {} 153 | 154 | function node:value() return self.___value end 155 | function node:setValue(val) self.___value = val end 156 | function node:name() return self.___name end 157 | function node:setName(name) self.___name = name end 158 | function node:children() return self.___children end 159 | function node:numChildren() return #self.___children end 160 | function node:addChild(child) 161 | if self[child:name()] ~= nil then 162 | if type(self[child:name()].name) == "function" then 163 | local tempTable = {} 164 | table.insert(tempTable, self[child:name()]) 165 | self[child:name()] = tempTable 166 | end 167 | table.insert(self[child:name()], child) 168 | else 169 | self[child:name()] = child 170 | end 171 | table.insert(self.___children, child) 172 | end 173 | 174 | function node:properties() return self.___props end 175 | function node:numProperties() return #self.___props end 176 | function node:addProperty(name, value) 177 | local lName = "@" .. name 178 | if self[lName] ~= nil then 179 | if type(self[lName]) == "string" then 180 | local tempTable = {} 181 | table.insert(tempTable, self[lName]) 182 | self[lName] = tempTable 183 | end 184 | table.insert(self[lName], value) 185 | else 186 | self[lName] = value 187 | end 188 | table.insert(self.___props, { name = name, value = self[lName] }) 189 | end 190 | 191 | return node 192 | end 193 | 194 | return _M -------------------------------------------------------------------------------- /ccext/csd2lua.lua: -------------------------------------------------------------------------------- 1 | --[[*************************************************************************** 2 | A tools to convert a Cocos Studio .csd file to a .lua resource file 3 | https://github.com/liangX-cn/csd2lua 4 | 5 | Require: 6 | Cocos2d-x Lua Project (Tested on Cocos2d-x 3.6) 7 | XmlParser.lua 8 | 9 | Usage: 10 | require(THIS_LUA).new():csd2lua(csdFullPathFileName, luaFullPathFileName) 11 | 12 | --***************************************************************************]] 13 | 14 | local _M = class("csd2lua") 15 | 16 | --///////////////////////////////////////////////////////////////////////////// 17 | local _SCRIPT_HELPER = 18 | [[ 19 | -- exported by csd2lua tools: https://github.com/liangX-cn/csd2lua 20 | 21 | local _L = require("ccext.LuaResHelper") 22 | ]] 23 | 24 | local _SCRIPT_HEAD = 25 | [[ 26 | 27 | local _M = { CCSVER = "%s" } 28 | 29 | ]] 30 | 31 | local _CREATE_FUNC_HEAD = 32 | [[ 33 | function _M.create(callBackProvider) 34 | local cc, ccui, ccs = cc, ccui, ccs 35 | local ccspc = cc.SpriteFrameCache:getInstance() 36 | local ccsam = ccs.ArmatureDataManager:getInstance() 37 | 38 | local setValue, bind = _L.setValue, _L.bind 39 | local setBgColor, setBgImage = _L.setBgColor, _L.setBgImage 40 | local setClickEvent, setTouchEvent = _L.setClickEvent, _L.setTouchEvent 41 | 42 | local roots, obj, inc = {} 43 | 44 | ]] 45 | 46 | local _CREATE_FUNC_FOOT = 47 | [[ 48 | return roots 49 | end 50 | 51 | ]] 52 | 53 | local _SCRIPT_FOOT = 54 | [[ 55 | 56 | return _M 57 | ]] 58 | 59 | --///////////////////////////////////////////////////////////////////////////// 60 | local function nextSiblingIter(node) 61 | local i, c, a = 1, node:numChildren(), node:children() 62 | return function() 63 | if i <= c then 64 | local n = a[i] 65 | i = i + 1 66 | return n 67 | end 68 | return nil 69 | end 70 | end 71 | 72 | local function isPointEqual(pt, values) 73 | return pt.x == values[1] and pt.y == values[2] 74 | end 75 | 76 | local function isSizeEqual(siz, values) 77 | return siz.width == values[1] and siz.height == values[2] 78 | end 79 | 80 | local function isColorEqual(clr, values) 81 | if clr.r ~= values[1] or clr.g ~= values[2] or clr.b ~= values[3] or (clr.a and clr.a ~= values[4]) then 82 | return false 83 | end 84 | return true 85 | end 86 | 87 | local function formatColor(value) 88 | if value and value[4] then 89 | return string.format("cc.c4b(%s, %s, %s, %s)", tostring(value[1]), tostring(value[2]), tostring(value[3]), tostring(value[4])) 90 | elseif value then 91 | return string.format("cc.c3b(%s, %s, %s)", tostring(value[1]), tostring(value[2]), tostring(value[3])) 92 | else 93 | return "nil" 94 | end 95 | end 96 | 97 | local function formatSize(value) 98 | if value then 99 | return string.format("cc.size(%s, %s)", tostring(value[1] or 0), tostring(value[2] or 0)) 100 | else 101 | return "nil" 102 | end 103 | end 104 | 105 | local function formatPoint(value) 106 | if value then 107 | return string.format("cc.p(%s, %s)", tostring(value[1] or 0), tostring(value[2] or 0)) 108 | else 109 | return "nil" 110 | end 111 | end 112 | 113 | local function formatString(value) 114 | if string.find(value, "[", 1, true) or string.find(value, "]", 1, true) then 115 | local i, s, f, e = 1 116 | while true do 117 | s = string.rep("=", i) 118 | f = "[" .. s .. "[" 119 | e = "]" .. s .. "]" 120 | 121 | if not string.find(value, f, 1, true) and not string.find(value, e, 1, true) then 122 | return f .. value .. e 123 | end 124 | 125 | i = i + 1 126 | end 127 | end 128 | return "[[" .. value .. "]]" 129 | end 130 | 131 | local function resourceType(t) 132 | if t == "Normal" or t == "Default" or t == "MarkedSubImage" then 133 | return 0 134 | else -- PlistSubImage 135 | return 1 136 | end 137 | end 138 | 139 | --///////////////////////////////////////////////////////////////////////////// 140 | 141 | 142 | --///////////////////////////////////////////////////////////////////////////// 143 | function _M:onProperty_Node(obj, name, value) 144 | local opts = self.opts 145 | local lays = self.lays 146 | 147 | if name == "Name" then 148 | opts[name] = value 149 | elseif name == "Tag" or name == "RotationSkewX" or name == "RotationSkewY" then 150 | opts[name] = tonumber(value) or 0 151 | elseif name == "Rotation" then 152 | elseif name == "FlipX" or name == "FlipY" then 153 | opts["Flipped" .. string.sub(name, 5)] = (value == "True") 154 | elseif name == "ZOrder" then 155 | opts["LocalZOrder"] = tonumber(value) or 0 156 | elseif name == "Visible" then 157 | elseif name == "VisibleForFrame" then 158 | opts["Visible"] = (value == "True") 159 | elseif name == "Alpha" then 160 | opts["Opacity"] = tonumber(value) or 255 161 | elseif name == "TouchEnable" then 162 | opts[name .. "d"] = (value == "True") 163 | elseif name == "UserData" then 164 | elseif name == "FrameEvent" then 165 | elseif name == "CallBackType" or name == "CallBackName" then 166 | opts["Callback" .. string.sub(name, 9)] = value 167 | elseif name == "PositionPercentXEnabled" or name == "PositionPercentYEnabled" or 168 | name == "PercentWidthEnabled" or name == "PercentHeightEnabled" or 169 | name == "StretchWidthEnable" or name == "StretchHeightEnable" then 170 | lays[name] = (value == "True") 171 | -- fix bad name likes PercentHeightEnable 172 | elseif name == "PositionPercentXEnable" or name == "PositionPercentYEnable" or 173 | name == "PercentWidthEnable" or name == "PercentHeightEnable" then 174 | lays[name .. "d"] = (value == "True") 175 | elseif name == "HorizontalEdge" or name == "VerticalEdge" then 176 | if value == "LeftEdge" or value == "BottomEdge" then 177 | lays[name] = 1 178 | elseif value == "RightEdge" or value == "TopEdge" then 179 | lays[name] = 2 180 | elseif value == "BothEdge" then 181 | lays[name] = 3 182 | end 183 | elseif name == "LeftMargin" or name == "RightMargin" or 184 | name == "TopMargin" or name == "BottomMargin" then 185 | lays[name] = tonumber(value) or 0 186 | elseif name == "Scale9Enable" then 187 | opts["Scale9Enabled"] = (value == "True") 188 | elseif name == "Scale9OriginX" or name == "Scale9OriginY" or 189 | name == "Scale9Width" or name == "Scale9Height" then 190 | opts[name] = tonumber(value) or 0 191 | elseif name == "FontSize" then 192 | opts[name] = tonumber(value) or 22 193 | elseif name == "FontName" then 194 | opts[name] = value 195 | elseif name == "DisplayState" or name == "IsCustomSize" or name == "OutlineEnabled" or name == "ShadowEnabled" then 196 | opts[name] = (value == "True") 197 | elseif name == "OutlineSize" or name == "ShadowOffsetX" or name == "ShadowOffsetY" or name == "ShadowBlurRadius" then 198 | opts[name] = tonumber(value) or 0 199 | else 200 | return false 201 | end 202 | 203 | -- print("onProperty_Node(" .. name .. ", " .. tostring(value) .. ")") 204 | return true 205 | end 206 | 207 | function _M:onChildren_Node(obj, name, c) 208 | local opts = self.opts 209 | local lays = self.lays 210 | 211 | if name == "Position" then 212 | opts[name] = { tonumber(c["@X"]) or 0, tonumber(c["@Y"]) or 0 } 213 | elseif name == "Scale" then 214 | opts[name] = { tonumber(c["@ScaleX"]) or 1, tonumber(c["@ScaleY"]) or 1 } 215 | elseif name == "AnchorPoint" then 216 | opts[name] = { tonumber(c["@ScaleX"]) or 0, tonumber(c["@ScaleY"]) or 0 } 217 | elseif name == "CColor" then 218 | opts["Color"] = { 219 | tonumber(c["@R"]) or 0, tonumber(c["@G"]) or 0, 220 | tonumber(c["@B"]) or 0, tonumber(c["@A"]) 221 | } 222 | elseif name == "Size" then 223 | opts[name] = { tonumber(c["@X"]) or 0, tonumber(c["@Y"]) or 0 } 224 | elseif name == "PrePosition" then 225 | lays["PositionPercentX"] = tonumber(c["@X"]) or 0 226 | lays["PositionPercentY"] = tonumber(c["@Y"]) or 0 227 | elseif name == "PreSize" then 228 | lays["PercentWidth"] = tonumber(c["@X"]) or 0 229 | lays["PercentHeight"] = tonumber(c["@Y"]) or 0 230 | elseif name == "FileData" then 231 | local f, t, p = c["@Path"] or "", resourceType(c["@Type"]), c["@Plist"] or "" 232 | if #p > 0 then 233 | self:addTexture(t, p) 234 | else 235 | self:addTexture(t, f) 236 | end 237 | opts[name] = { f, t, p } 238 | elseif name == "OutlineColor" or name == "ShadowColor" then 239 | opts[name] = { 240 | tonumber(c["@R"]) or 0, tonumber(c["@G"]) or 0, 241 | tonumber(c["@B"]) or 0, tonumber(c["@A"]) or 0 242 | } 243 | elseif name == "FontResource" then 244 | else 245 | return false 246 | end 247 | 248 | return true 249 | end 250 | 251 | function _M:handleOpts_Node(obj) 252 | local opts = self.opts 253 | local lays = self.lays 254 | 255 | local tblVal, tblTmp, str = {}, {}, "" 256 | 257 | if opts.CallbackType and opts.CallbackName and 258 | (opts.CallbackType == "Click" or opts.CallbackType == "Touch") then 259 | table.insert(tblVal, string.format(" set%sEvent(obj, callBackProvider, \"%s\")\n", 260 | opts.CallbackType, opts.CallbackName)) 261 | end 262 | 263 | for name, value in pairs(opts) do 264 | str = "" 265 | if name == "Name" then 266 | local pos = string.find(value, "@class_") 267 | if pos then 268 | value = string.sub(value, 1, pos - 1) 269 | end 270 | tblTmp[name] = value 271 | elseif name == "Tag" or name == "LocalZOrder" or name == "Opacity" then 272 | if obj["get" .. name](obj) ~= value then 273 | tblTmp[name] = value 274 | end 275 | elseif name == "RotationSkewX" or name == "RotationSkewY" or 276 | name == "FlippedX" or name == "FlippedY" or name == "Visible" or name == "TouchEnabled" then 277 | if (type(obj["get" .. name]) == "function" and obj["get" .. name](obj) ~= value) or 278 | (type(obj["is" .. name]) == "function" and obj["is" .. name](obj) ~= value) then 279 | str = string.format("obj:set%s(%s)\n", name, tostring(value)) 280 | end 281 | elseif name == "Position" or name == "Scale" then 282 | if obj["get" .. name .. "X"](obj) ~= value[1] or 283 | obj["get" .. name .. "Y"](obj) ~= value[2] then 284 | if name == "Scale" then 285 | str = string.format("obj:set%s(%s, %s)\n", name, tostring(value[1]), tostring(value[2])) 286 | else 287 | tblTmp[name] = value 288 | end 289 | end 290 | elseif name == "AnchorPoint" then 291 | if not isPointEqual(obj["get" .. name](obj), value) then 292 | tblTmp[name] = value 293 | end 294 | elseif name == "Size" then 295 | -- getSize is deprecated, use getContentSize 296 | if type(obj["getContentSize"]) == "function" and not isSizeEqual(obj["getContentSize"](obj), value) then 297 | tblTmp[name] = value 298 | end 299 | elseif name == "Color" then 300 | if not isColorEqual(obj:getColor(), value) then 301 | tblTmp[name] = value 302 | end 303 | end 304 | 305 | if #str > 0 then 306 | table.insert(tblVal, " " .. str) 307 | end 308 | end 309 | 310 | self:writef(" setValue(obj, \"%s\", %s, %s, %s, %s, %s, %s, %s, %s)\n", 311 | tostring(tblTmp.Name), tostring(tblTmp.Tag), formatSize(tblTmp.Size), formatPoint(tblTmp.Position), formatPoint(tblTmp.AnchorPoint), 312 | formatColor(tblTmp.Color), tostring(tblTmp.Opacity), tostring(tblTmp.LocalZOrder), tostring(opts.IgnoreContentAdaptWithSize)) 313 | 314 | if #tblVal > 0 then 315 | self:write(table.concat(tblVal)) 316 | end 317 | end 318 | 319 | --///////////////////////////////////////////////////////////////////////////// 320 | function _M:onProperty_ImageView(obj, name, value) 321 | -- nothing to do 322 | return self:onProperty_Node(obj, name, value) 323 | end 324 | 325 | function _M:onChildren_ImageView(obj, name, c) 326 | -- local opts = self.opts 327 | -- 328 | -- if name == "Size" and opts.Scale9Enabled then 329 | -- opts["Scale9Size"] = { tonumber(c["@X"]) or 0, tonumber(c["@Y"]) or 0 } 330 | -- else 331 | return self:onChildren_Node(obj, name, c) 332 | -- end 333 | -- 334 | -- print("onChildren_ImageView(" .. name .. ", " .. tostring(opts[name]) .. ")") 335 | -- return true 336 | end 337 | 338 | function _M:handleOpts_ImageView(obj) 339 | local opts = self.opts 340 | 341 | if opts.Scale9Enabled then 342 | local capInsets = string.format("cc.rect(%s, %s, %s, %s)", 343 | tostring(opts.Scale9OriginX or 0), tostring(opts.Scale9OriginY or 0), 344 | tostring(opts.Scale9Width or 0), tostring(opts.Scale9Height or 0)) 345 | 346 | self:write(" obj:setScale9Enabled(true)\n") 347 | self:write(" obj:setCapInsets(" .. capInsets .. ")\n") 348 | -- 349 | -- if opts.Scale9Size then 350 | -- self:writef(" obj:setContentSize(%s)\n", formatSize(opts.Scale9Size)) 351 | -- end 352 | end 353 | 354 | if opts.Size and obj:isIgnoreContentAdaptWithSize() then 355 | opts["IgnoreContentAdaptWithSize"] = false 356 | end 357 | 358 | self:handleOpts_Node(obj) 359 | 360 | if opts.FileData then 361 | self:writef(" obj:loadTexture(\"%s\", %s)\n", tostring(opts.FileData[1]), tostring(opts.FileData[2])) 362 | end 363 | end 364 | 365 | --///////////////////////////////////////////////////////////////////////////// 366 | function _M:onProperty_Button(obj, name, value) 367 | local opts = self.opts 368 | 369 | if name == "ButtonText" then 370 | opts[name] = value 371 | else 372 | return self:onProperty_Node(obj, name, value) 373 | end 374 | 375 | -- print("onProperty_Button(" .. name .. ", " .. tostring(value) .. ")") 376 | return true 377 | end 378 | 379 | function _M:onChildren_Button(obj, name, c) 380 | local opts = self.opts 381 | 382 | if name == "TextColor" then 383 | opts[name] = { 384 | tonumber(c["@R"]) or 0, tonumber(c["@G"]) or 0, 385 | tonumber(c["@B"]) or 0 386 | } 387 | elseif name == "NormalFileData" or name == "PressedFileData" or name == "DisabledFileData" then 388 | local f, t, p = c["@Path"] or "", resourceType(c["@Type"]), c["@Plist"] or "" 389 | if #p > 0 then 390 | self:addTexture(t, p) 391 | else 392 | self:addTexture(t, f) 393 | end 394 | opts[name] = { f, t, p } 395 | -- elseif name == "Size" and opts.Scale9Enabled then 396 | -- opts["Scale9Size"] = { tonumber(c["@X"]) or 0, tonumber(c["@Y"]) or 0 } 397 | else 398 | return self:onChildren_Node(obj, name, c) 399 | end 400 | 401 | -- print("onChildren_Button(" .. name .. ", " .. tostring(opts[name]) .. ")") 402 | return true 403 | end 404 | 405 | function _M:handleOpts_Button(obj) 406 | local opts = self.opts 407 | 408 | if opts.Scale9Enabled then 409 | local capInsets = string.format("cc.rect(%s, %s, %s, %s)", 410 | tostring(opts.Scale9OriginX or 0), tostring(opts.Scale9OriginY or 0), 411 | tostring(opts.Scale9Width or 0), tostring(opts.Scale9Height or 0)) 412 | 413 | self:write(" obj:setCapInsets(" .. capInsets .. ")\n") 414 | -- 415 | -- if opts.Scale9Size then 416 | -- self:writef(" obj:setContentSize(%s)\n", formatSize(opts.Scale9Size)) 417 | -- end 418 | end 419 | 420 | self:handleOpts_Node(obj) 421 | 422 | if opts.NormalFileData then 423 | self:writef(" obj:loadTextureNormal(\"%s\", %s)\n", tostring(opts.NormalFileData[1]), tostring(opts.NormalFileData[2])) 424 | end 425 | 426 | if opts.PressedFileData then 427 | self:writef(" obj:loadTexturePressed(\"%s\", %s)\n", tostring(opts.PressedFileData[1]), tostring(opts.PressedFileData[2])) 428 | end 429 | 430 | if opts.DisabledFileData then 431 | self:writef(" obj:loadTextureDisabled(\"%s\", %s)\n", tostring(opts.DisabledFileData[1]), tostring(opts.DisabledFileData[2])) 432 | end 433 | 434 | if opts.FontResource then 435 | end 436 | 437 | if nil ~= opts.DisplayState then 438 | if obj:isBright() ~= opts.DisplayState then 439 | self:writef(" obj:setBright(%s)\n", tostring(opts.DisplayState)) 440 | end 441 | 442 | if obj:isEnabled() ~= opts.DisplayState then 443 | self:writef(" obj:setEnabled(%s)\n", tostring(opts.DisplayState)) 444 | end 445 | end 446 | 447 | if opts.OutlineEnabled then 448 | self:writef(" obj:enableOutline(%s, %s)\n", formatColor(opts.OutlineColor or { 0, 0, 0, 0 }), tostring(opts.OutlineSize or 0)) 449 | end 450 | 451 | if opts.ShadowEnabled then 452 | self:writef(" obj:enableShadow(%s, cc.size(%d, %d), %s)\n", 453 | formatColor(opts.ShadowColor or { 0, 0, 0, 0 }), tonumber(opts.ShadowOffsetX) or 0, tonumber(opts.ShadowOffsetY) or 0, tostring(opts.ShadowBlurRadius or 0)) 454 | end 455 | 456 | if opts.ButtonText and not obj:getTitleText() ~= opts.ButtonText then 457 | self:write(" obj:setTitleText(" .. formatString(opts.ButtonText) .. ")\n") 458 | end 459 | 460 | if opts.TextColor and not isColorEqual(obj:getTitleColor(), opts.TextColor) then 461 | self:write(" obj:setTitleColor(" .. formatColor(opts.TextColor) .. ")\n") 462 | end 463 | 464 | if opts.FontSize and obj:getTitleFontSize() ~= opts.FontSize then 465 | self:write(" obj:setTitleFontSize(" .. tostring(opts.FontSize) .. ")\n") 466 | end 467 | 468 | if opts.FontName and obj:getTitleFontName() ~= opts.FontName then 469 | self:write(" obj:setTitleFontName(" .. formatString(opts.FontName) .. ")\n") 470 | end 471 | end 472 | 473 | --///////////////////////////////////////////////////////////////////////////// 474 | function _M:onProperty_Text(obj, name, value) 475 | local opts = self.opts 476 | 477 | if name == "TouchScaleChangeAble" then 478 | opts["TouchScaleEnabled"] = (value == "True") 479 | elseif name == "LabelText" then 480 | opts[name] = value 481 | elseif name == "AreaWidth" or name == "AreaHeight" then 482 | opts[name] = tonumber(value) or 0 483 | elseif name == "HorizontalAlignmentType" then 484 | if value == "HT_Left" then 485 | opts["TextHorizontalAlignment"] = 0 486 | elseif value == "HT_Center" then 487 | opts["TextHorizontalAlignment"] = 1 488 | elseif value == "HT_Right" then 489 | opts["TextHorizontalAlignment"] = 2 490 | end 491 | elseif name == "VerticalAlignmentType" then 492 | if value == "VT_Top" then 493 | opts["TextVerticalAlignment"] = 0 494 | elseif value == "VT_Center" then 495 | opts["TextVerticalAlignment"] = 1 496 | elseif value == "VT_Bottom" then 497 | opts["TextVerticalAlignment"] = 2 498 | end 499 | else 500 | return self:onProperty_Node(obj, name, value) 501 | end 502 | 503 | -- print("onProperty_Text(" .. name .. ", " .. tostring(value) .. ")") 504 | return true 505 | end 506 | 507 | function _M:onChildren_Text(obj, name, c) 508 | -- nothing to do 509 | return self:onChildren_Node(obj, name, c) 510 | end 511 | 512 | function _M:handleOpts_Text(obj) 513 | local opts = self.opts 514 | 515 | self:handleOpts_Node(obj) 516 | 517 | if opts.LabelText then 518 | self:writef(" obj:setString(%s)\n", formatString(opts.LabelText)) 519 | end 520 | 521 | if opts.FontSize and obj:getFontSize() ~= opts.FontSize then 522 | self:writef(" obj:setFontSize(%s)\n", tostring(opts.FontSize)) 523 | end 524 | 525 | if opts.FontName and obj:getFontName() ~= opts.FontName then 526 | self:writef(" obj:FontName(\"%s\")\n", tostring(opts.FontName)) 527 | end 528 | 529 | if nil ~= opts.TouchScaleChangeAble and obj:isTouchScaleChangeAble() ~= opts.TouchScaleChangeAble then 530 | self:writef(" obj:setTouchScaleChangeAble(%s)\n", tostring(opts.TouchScaleChangeAble)) 531 | end 532 | 533 | if (nil ~= opts.AreaWidth or nil ~= opts.AreaHeight) and 534 | obj:getTextAreaSize().width ~= (opts.opts.AreaWidth or 0) and 535 | obj:getTextAreaSize().height ~= (opts.opts.AreaHeight or 0) then 536 | self:writef(" obj:setTextAreaSize(cc.size(%s))\n", tostring(opts.AreaWidth or 0), tostring(opts.AreaHeight or 0)) 537 | end 538 | 539 | if opts.TextHorizontalAlignment and obj:getTextHorizontalAlignment() ~= opts.TextHorizontalAlignment then 540 | self:writef(" obj:setTextHorizontalAlignment(%s)\n", tostring(opts.TextHorizontalAlignment)) 541 | end 542 | 543 | if opts.TextVerticalAlignment and obj:getTextVerticalAlignment() ~= opts.TextVerticalAlignment then 544 | self:writef(" obj:setTextVerticalAlignment(%s)\n", tostring(opts.TextVerticalAlignment)) 545 | end 546 | 547 | if opts.OutlineEnabled then 548 | self:writef(" obj:enableOutline(%s, %s)\n", formatColor(opts.OutlineColor or { 0, 0, 0, 0 }), tostring(opts.OutlineSize or 0)) 549 | end 550 | 551 | if opts.ShadowEnabled then 552 | self:writef(" obj:enableShadow(%s, cc.size(%d, %d), %s)\n", 553 | formatColor(opts.ShadowColor or { 0, 0, 0, 0 }), tonumber(opts.ShadowOffsetX) or 0, tonumber(opts.ShadowOffsetY) or 0, tostring(opts.ShadowBlurRadius or 0)) 554 | end 555 | 556 | if opts.Color and not isColorEqual(obj:getTextColor(), opts.Color) then 557 | self:writef(" obj:setTextColor(%s)\n", formatColor(opts.Color)) 558 | end 559 | end 560 | 561 | --///////////////////////////////////////////////////////////////////////////// 562 | function _M:onProperty_RichTextEx(obj, name, value) 563 | -- nothing to do 564 | return self:onProperty_Text(obj, name, value) 565 | end 566 | 567 | function _M:onChildren_RichTextEx(obj, name, c) 568 | -- nothing to do 569 | return self:onChildren_Text(obj, name, c) 570 | end 571 | 572 | function _M:handleOpts_RichTextEx(obj) 573 | local opts = self.opts 574 | 575 | if nil ~= opts.AreaWidth or nil ~= opts.AreaHeight then 576 | opts["IgnoreContentAdaptWithSize"] = false 577 | end 578 | 579 | self:handleOpts_Node(obj) 580 | 581 | if opts.FontSize and obj:getFontSizeDef() ~= opts.FontSize then 582 | self:writef(" obj:setFontSizeDef(%s)\n", tostring(opts.FontSize)) 583 | end 584 | 585 | if opts.Color and not isColorEqual(obj:getTextColorDef(), opts.Color) then 586 | self:writef(" obj:setTextColorDef(%s)\n", formatColor(opts.Color)) 587 | end 588 | 589 | if opts.TextHorizontalAlignment or opts.TextVerticalAlignment then 590 | self:writef(" obj:setAlignment(%d, %d)\n", tonumber(opts.TextHorizontalAlignment) or 0, tonumber(opts.TextVerticalAlignment) or 0) 591 | end 592 | 593 | if opts.LabelText then 594 | self:writef(" obj:setString(%s)\n", formatString(opts.LabelText)) 595 | end 596 | 597 | print("handleOpts_RichTextEx") 598 | end 599 | 600 | --///////////////////////////////////////////////////////////////////////////// 601 | function _M:onProperty_TextField(obj, name, value) 602 | local opts = self.opts 603 | 604 | if name == "LabelText" or name == "PlaceHolderText" or name == "PasswordStyleText" then 605 | opts[name] = value 606 | elseif name == "MaxLengthEnable" or name == "PasswordEnable" then 607 | opts[name .. "d"] = (value == "True") 608 | elseif name == "MaxLengthText" then 609 | opts["MaxLength"] = tonumber(value) or 0 610 | elseif name == "PasswordStyleText" then 611 | opts["PasswordStyle"] = value 612 | else 613 | return self:onProperty_Node(obj, name, value) 614 | end 615 | 616 | -- print("onProperty_TextField(" .. name .. ", " .. tostring(value) .. ")") 617 | return true 618 | end 619 | 620 | function _M:onChildren_TextField(obj, name, c) 621 | -- nothing to do 622 | return self:onChildren_Node(obj, name, c) 623 | end 624 | 625 | function _M:handleOpts_TextField(obj) 626 | self:handleOpts_Node(obj) 627 | 628 | local opts = self.opts 629 | 630 | if opts.LabelText then 631 | self:writef(" obj:setString(%s)\n", formatString(opts.LabelText)) 632 | end 633 | 634 | if opts.PlaceHolderText then 635 | self:writef(" obj:setPlaceHolder(%s)\n", formatString(opts.PlaceHolderText)) 636 | end 637 | 638 | if opts.FontSize and obj:getFontSize() ~= opts.FontSize then 639 | self:writef(" obj:setFontSize(%s)\n", tostring(opts.FontSize)) 640 | end 641 | 642 | if opts.FontName and obj:getFontName() ~= opts.FontName then 643 | self:writef(" obj:FontName(\"%s\")\n", tostring(opts.FontName)) 644 | end 645 | 646 | if opts.MaxLengthEnabled then 647 | if obj:isMaxLengthEnabled() ~= opts.MaxLengthEnabled then 648 | self:writef(" obj:setMaxLengthEnabled(%s)\n", tostring(opts.MaxLengthEnabled)) 649 | end 650 | 651 | if opts.MaxLength and obj:getMaxLength() ~= opts.MaxLength then 652 | self:writef(" obj:setMaxLength(%s)\n", tostring(opts.MaxLength)) 653 | end 654 | end 655 | 656 | if opts.PasswordEnabled then 657 | if obj:isPasswordEnabled() ~= opts.PasswordEnabled then 658 | self:writef(" obj:setPasswordEnabled(%s)\n", tostring(opts.PasswordEnabled)) 659 | end 660 | 661 | if opts.PasswordStyleText then 662 | self:writef(" obj:setPasswordStyleText(%s)\n", formatString(opts.PasswordStyleText)) 663 | end 664 | end 665 | end 666 | 667 | --///////////////////////////////////////////////////////////////////////////// 668 | function _M:onProperty_EditBox(obj, name, value) 669 | -- nothing to do 670 | return self:onProperty_TextField(obj, name, value) 671 | end 672 | 673 | function _M:onChildren_EditBox(obj, name, c) 674 | -- nothing to do 675 | return self:onChildren_TextField(obj, name, c) 676 | end 677 | 678 | function _M:handleOpts_EditBox(obj) 679 | self:handleOpts_Node(obj) 680 | 681 | local opts = self.opts 682 | 683 | if opts.LabelText then 684 | self:writef(" obj:setText(%s)\n", formatString(opts.LabelText)) 685 | end 686 | 687 | 688 | if opts.PlaceHolderText then 689 | self:writef(" obj:setPlaceHolder(%s)\n", formatString(opts.PlaceHolderText)) 690 | end 691 | 692 | if opts.FontSize then 693 | self:writef(" obj:setFontSize(%s)\n", tostring(opts.FontSize)) 694 | end 695 | 696 | if opts.Color then 697 | self:writef(" obj:setFontColor(%s)\n", formatColor(opts.Color)) 698 | end 699 | 700 | if opts.FontName then 701 | self:writef(" obj:FontName(\"%s\")\n", tostring(opts.FontName)) 702 | self:writef(" obj:PlaceHolderFontName(\"%s\")\n", tostring(opts.FontName)) 703 | end 704 | 705 | if opts.MaxLengthEnabled and opts.MaxLength then 706 | self:writef(" obj:setMaxLength(%s)\n", tostring(opts.MaxLength)) 707 | end 708 | 709 | if opts.PasswordEnabled then 710 | self:write(" obj:setInputFlag(cc.EDITBOX_INPUT_FLAG_PASSWORD)\n") 711 | end 712 | 713 | self:write(" obj:setReturnType(cc.KEYBOARD_RETURNTYPE_DONE)\n") 714 | self:write(" obj:setInputMode(cc.EDITBOX_INPUT_MODE_SINGLELINE)\n") 715 | end 716 | 717 | --///////////////////////////////////////////////////////////////////////////// 718 | function _M:onProperty_TextAtlas(obj, name, value) 719 | local opts = self.opts 720 | 721 | if name == "LabelText" or name == "StartChar" then 722 | opts[name] = value 723 | elseif name == "CharWidth" or name == "CharHeight" then 724 | opts[name] = tonumber(value) or 0 725 | else 726 | return self:onProperty_Node(obj, name, value) 727 | end 728 | 729 | -- print("onProperty_TextAtlas(" .. name .. ", " .. tostring(value) .. ")") 730 | return true 731 | end 732 | 733 | function _M:onChildren_TextAtlas(obj, name, c) 734 | local opts = self.opts 735 | 736 | if name == "LabelAtlasFileImage_CNB" then 737 | local f = c["@Path"] or "", 0, "" 738 | self:addTexture(0, f) 739 | opts[name] = f 740 | else 741 | return self:onChildren_Node(obj, name, c) 742 | end 743 | 744 | -- print("onChildren_TextAtlas(" .. name .. ", " .. tostring(opts[name]) .. ")") 745 | return true 746 | end 747 | 748 | function _M:handleOpts_TextAtlas(obj) 749 | local opts = self.opts 750 | 751 | if not obj:isIgnoreContentAdaptWithSize() then 752 | opts["IgnoreContentAdaptWithSize"] = true 753 | end 754 | 755 | self:handleOpts_Node(obj) 756 | 757 | if opts.LabelAtlasFileImage_CNB and opts.StartChar and opts.CharWidth and opts.CharHeight then 758 | self:writef(" obj:setProperty(%s, \"%s\", %s, %s, %s)\n", 759 | formatString(opts.LabelText), opts.LabelAtlasFileImage_CNB, 760 | tostring(opts.CharWidth), tostring(opts.CharHeight), 761 | formatString(opts.StartChar)) 762 | end 763 | end 764 | 765 | --///////////////////////////////////////////////////////////////////////////// 766 | function _M:onProperty_TextBMFont(obj, name, value) 767 | local opts = self.opts 768 | 769 | if name == "LabelText" then 770 | opts[name] = value 771 | else 772 | return self:onProperty_Node(obj, name, value) 773 | end 774 | 775 | -- print("onProperty_TextBMFont(" .. name .. ", " .. tostring(value) .. ")") 776 | return true 777 | end 778 | 779 | function _M:onChildren_TextBMFont(obj, name, c) 780 | local opts = self.opts 781 | 782 | if name == "LabelBMFontFile_CNB" then 783 | local f = c["@Path"] or "", 0, "" 784 | -- self:addTexture(0, f) 785 | opts[name] = f 786 | else 787 | return self:onChildren_Node(obj, name, c) 788 | end 789 | 790 | -- print("onChildren_TextBMFont(" .. name .. ", " .. tostring(opts[name]) .. ")") 791 | return true 792 | end 793 | 794 | function _M:handleOpts_TextBMFont(obj) 795 | local opts = self.opts 796 | 797 | if not obj:isIgnoreContentAdaptWithSize() then 798 | opts["IgnoreContentAdaptWithSize"] = true 799 | end 800 | 801 | self:handleOpts_Node(obj) 802 | 803 | if opts.LabelText then 804 | self:writef(" obj:setString(%s)\n", formatString(opts.LabelText)) 805 | end 806 | 807 | if opts.LabelBMFontFile_CNB then 808 | self:writef(" obj:setFntFile(\"%s\")\n", opts.LabelBMFontFile_CNB) 809 | end 810 | end 811 | 812 | --///////////////////////////////////////////////////////////////////////////// 813 | function _M:onProperty_CheckBox(obj, name, value) 814 | local opts = self.opts 815 | 816 | if name == "CheckedState" or name == "DisplayState" then 817 | opts[name] = (value == "True") 818 | else 819 | return self:onProperty_Node(obj, name, value) 820 | end 821 | 822 | -- print("onProperty_CheckBox(" .. name .. ", " .. tostring(value) .. ")") 823 | return true 824 | end 825 | 826 | function _M:onChildren_CheckBox(obj, name, c) 827 | local opts = self.opts 828 | 829 | if name == "NormalBackFileData" or name == "PressedBackFileData" or name == "DisableBackFileData" or 830 | name == "NodeNormalFileData" or name == "NodeDisableFileData" then 831 | local f, t, p = c["@Path"] or "", resourceType(c["@Type"]), c["@Plist"] or "" 832 | if #p > 0 then 833 | self:addTexture(t, p) 834 | else 835 | self:addTexture(t, f) 836 | end 837 | opts[name] = { f, t, p } 838 | else 839 | return self:onChildren_Node(obj, name, c) 840 | end 841 | 842 | -- print("onChildren_CheckBox(" .. name .. ", " .. tostring(opts[name]) .. ")") 843 | return true 844 | end 845 | 846 | function _M:handleOpts_CheckBox(obj) 847 | self:handleOpts_Node(obj) 848 | 849 | local opts = self.opts 850 | 851 | if opts.NormalBackFileData then 852 | self:writef(" obj:loadTextureBackGround(\"%s\", %s)\n", tostring(opts.NormalBackFileData[1]), tostring(opts.NormalBackFileData[2])) 853 | end 854 | 855 | if opts.PressedBackFileData then 856 | self:writef(" obj:loadTextureBackGroundSelected(\"%s\", %s)\n", tostring(opts.PressedBackFileData[1]), tostring(opts.PressedBackFileData[2])) 857 | end 858 | 859 | if opts.DisableBackFileData then 860 | self:writef(" obj:loadTextureBackGroundDisabled(\"%s\", %s)\n", tostring(opts.DisableBackFileData[1]), tostring(opts.DisableBackFileData[2])) 861 | end 862 | 863 | if opts.NodeNormalFileData then 864 | self:writef(" obj:loadTextureFrontCross(\"%s\", %s)\n", tostring(opts.NodeNormalFileData[1]), tostring(opts.NodeNormalFileData[2])) 865 | end 866 | 867 | if opts.NodeDisableFileData then 868 | self:writef(" obj:loadTextureFrontCrossDisabled(\"%s\", %s)\n", tostring(opts.NodeDisableFileData[1]), tostring(opts.NodeDisableFileData[2])) 869 | end 870 | 871 | if nil ~= opts.CheckedState and obj:isSelected() ~= opts.CheckedState then 872 | self:writef(" obj:setSelected(%s)\n", tostring(opts.CheckedState)) 873 | end 874 | 875 | if nil ~= opts.DisplayState then 876 | if obj:isBright() ~= opts.DisplayState then 877 | self:writef(" obj:setBright(%s)\n", tostring(opts.DisplayState)) 878 | end 879 | 880 | if obj:isEnabled() ~= opts.DisplayState then 881 | self:writef(" obj:setEnabled(%s)\n", tostring(opts.DisplayState)) 882 | end 883 | end 884 | end 885 | 886 | --///////////////////////////////////////////////////////////////////////////// 887 | function _M:onProperty_Sprite(obj, name, value) 888 | -- nothing to do 889 | return self:onProperty_Node(obj, name, value) 890 | end 891 | 892 | function _M:onChildren_Sprite(obj, name, c) 893 | local opts = self.opts 894 | 895 | if name == "BlendFunc" then 896 | opts[name] = { tonumber(c["@Src"]) or 0, tonumber(c["@Dst"]) or 0 } 897 | else 898 | return self:onChildren_Node(obj, name, c) 899 | end 900 | 901 | -- print("onChildren_Sprite(" .. name .. ", " .. tostring(opts[name]) .. ")") 902 | return true 903 | end 904 | 905 | function _M:handleOpts_Sprite(obj) 906 | self:handleOpts_Node(obj) 907 | 908 | local opts = self.opts 909 | 910 | if opts.FileData then 911 | if opts.FileData[2] == 0 then 912 | self:writef(" obj:setTexture(\"%s\")\n", opts.FileData[1]) 913 | elseif opts.FileData[2] == 1 then 914 | self:writef(" obj:setSpriteFrame(\"%s\")\n", opts.FileData[1]) 915 | end 916 | end 917 | 918 | if opts.BlendFunc then 919 | -- TODO 920 | end 921 | end 922 | 923 | --///////////////////////////////////////////////////////////////////////////// 924 | function _M:onProperty_Particle(obj, name, value) 925 | -- nothing to do 926 | return self:onProperty_Node(obj, name, value) 927 | end 928 | 929 | function _M:onChildren_Particle(obj, name, c) 930 | local opts = self.opts 931 | 932 | if name == "FileData" then 933 | -- nothing to do(done in objScriptOf()) 934 | elseif name == "BlendFunc" then 935 | opts[name] = { tonumber(c["@Src"]) or 0, tonumber(c["@Dst"]) or 0 } 936 | else 937 | return self:onChildren_Node(obj, name, c) 938 | end 939 | 940 | -- print("onChildren_Particle(" .. name .. ", " .. tostring(opts[name]) .. ")") 941 | return true 942 | end 943 | 944 | function _M:handleOpts_Particle(obj) 945 | self:handleOpts_Node(obj) 946 | 947 | local opts = self.opts 948 | 949 | if opts.FileData then 950 | -- nothing to do(done in objScriptOf()) 951 | end 952 | 953 | if opts.BlendFunc then 954 | -- TODO 955 | end 956 | end 957 | 958 | --///////////////////////////////////////////////////////////////////////////// 959 | function _M:onProperty_TMXTiledMap(obj, name, value) 960 | -- nothing to do 961 | return self:onProperty_Node(obj, name, value) 962 | end 963 | 964 | function _M:onChildren_TMXTiledMap(obj, name, c) 965 | local opts = self.opts 966 | 967 | if name == "FileData" then 968 | -- nothing to do(done in objScriptOf()) 969 | else 970 | return self:onChildren_Node(obj, name, c) 971 | end 972 | 973 | -- print("onChildren_TMXTiledMap(" .. name .. ", " .. tostring(opts[name]) .. ")") 974 | return true 975 | end 976 | 977 | function _M:handleOpts_TMXTiledMap(obj) 978 | self:handleOpts_Node(obj) 979 | 980 | local opts = self.opts 981 | 982 | if opts.FileData then 983 | -- nothing to do(done in objScriptOf()) 984 | end 985 | end 986 | 987 | --///////////////////////////////////////////////////////////////////////////// 988 | function _M:onProperty_ProjectNode(obj, name, value) 989 | -- nothing to do 990 | return self:onProperty_Node(obj, name, value) 991 | end 992 | 993 | function _M:onChildren_ProjectNode(obj, name, c) 994 | local opts = self.opts 995 | 996 | if name == "FileData" then 997 | -- nothing to do(done in objScriptOf()) 998 | else 999 | return self:onChildren_Node(obj, name, c) 1000 | end 1001 | 1002 | -- print("onChildren_ProjectNode(" .. name .. ", " .. tostring(opts[name]) .. ")") 1003 | return true 1004 | end 1005 | 1006 | function _M:handleOpts_ProjectNode(obj) 1007 | self:handleOpts_Node(obj) 1008 | 1009 | local opts = self.opts 1010 | 1011 | if opts.FileData then 1012 | -- nothing to do(done in objScriptOf()) 1013 | end 1014 | end 1015 | 1016 | --///////////////////////////////////////////////////////////////////////////// 1017 | function _M:onProperty_Armature(obj, name, value) 1018 | local opts = self.opts 1019 | 1020 | if name == "IsLoop" or name == "IsAutoPlay" then 1021 | opts[name] = (value == "True") 1022 | elseif name == "CurrentAnimationName" then 1023 | opts[name] = value 1024 | else 1025 | return self:onProperty_Node(obj, name, value) 1026 | end 1027 | 1028 | -- print("onProperty_Armature(" .. name .. ", " .. tostring(value) .. ")") 1029 | return true 1030 | end 1031 | 1032 | function _M:onChildren_Armature(obj, name, c) 1033 | local opts = self.opts 1034 | 1035 | if name == "FileData" then 1036 | opts["ArmatureFileInfo"] = c["@Path"] 1037 | else 1038 | return self:onChildren_Node(obj, name, c) 1039 | end 1040 | 1041 | -- print("onChildren_Armature(" .. name .. ", " .. tostring(opts[name]) .. ")") 1042 | return true 1043 | end 1044 | 1045 | function _M:handleOpts_Armature(obj) 1046 | self:handleOpts_Node(obj) 1047 | 1048 | local opts = self.opts 1049 | 1050 | if opts.ArmatureFileInfo then 1051 | self:writef(" ccsam:addArmatureFileInfo(\"%s\")\n", opts.ArmatureFileInfo) 1052 | end 1053 | 1054 | self:write(" obj:init(\"DemoPlayer\")\n") 1055 | 1056 | if opts.CurrentAnimationName then 1057 | local loop = 0 1058 | if opts.IsLoop then loop = 1 end 1059 | if opts.IsAutoPlay then 1060 | self:writef(" obj:getAnimation():play(\"%s\", -1, %d)\n", opts.CurrentAnimationName, loop) 1061 | else 1062 | self:writef(" obj:getAnimation():play(\"%s\")\n", opts.CurrentAnimationName) 1063 | self:write(" obj:getAnimation():gotoAndPause(0)\n") 1064 | end 1065 | end 1066 | end 1067 | 1068 | --///////////////////////////////////////////////////////////////////////////// 1069 | function _M:onProperty_Slider(obj, name, value) 1070 | local opts = self.opts 1071 | 1072 | if name == "PercentInfo" then 1073 | opts["Percent"] = tonumber(value) or 0 1074 | else 1075 | return self:onProperty_Node(obj, name, value) 1076 | end 1077 | 1078 | -- print("onProperty_Slider(" .. name .. ", " .. tostring(value) .. ")") 1079 | return true 1080 | end 1081 | 1082 | function _M:onChildren_Slider(obj, name, c) 1083 | local opts = self.opts 1084 | 1085 | if name == "BackGroundData" or name == "ProgressBarData" or 1086 | name == "BallNormalData" or name == "BallPressedData" or name == "BallDisabledData" then 1087 | local f, t, p = c["@Path"] or "", resourceType(c["@Type"]), c["@Plist"] or "" 1088 | if #p > 0 then 1089 | self:addTexture(t, p) 1090 | else 1091 | self:addTexture(t, f) 1092 | end 1093 | opts[name] = { f, t, p } 1094 | else 1095 | return self:onChildren_Node(obj, name, c) 1096 | end 1097 | 1098 | -- print("onChildren_Slider(" .. name .. ", " .. tostring(opts[name]) .. ")") 1099 | return true 1100 | end 1101 | 1102 | function _M:handleOpts_Slider(obj) 1103 | self:handleOpts_Node(obj) 1104 | 1105 | local opts = self.opts 1106 | 1107 | if opts.Percent and obj:getPercent() ~= opts.Percent then 1108 | self:writef(" obj:setPercent(%s)\n", tostring(opts.Percent)) 1109 | end 1110 | 1111 | if opts.BackGroundData then 1112 | self:writef(" obj:loadBarTexture(\"%s\", %s)\n", tostring(opts.BackGroundData[1]), tostring(opts.BackGroundData[2])) 1113 | end 1114 | 1115 | if opts.BallNormalData then 1116 | self:writef(" obj:loadSlidBallTextureNormal(\"%s\", %s)\n", tostring(opts.BallNormalData[1]), tostring(opts.BallNormalData[2])) 1117 | end 1118 | 1119 | if opts.BallPressedData then 1120 | self:writef(" obj:loadSlidBallTexturePressed(\"%s\", %s)\n", tostring(opts.BallPressedData[1]), tostring(opts.BallPressedData[2])) 1121 | end 1122 | 1123 | if opts.BallDisabledData then 1124 | self:writef(" obj:loadSlidBallTextureDisabled(\"%s\", %s)\n", tostring(opts.BallDisabledData[1]), tostring(opts.BallDisabledData[2])) 1125 | end 1126 | 1127 | if opts.ProgressBarData then 1128 | self:writef(" obj:loadProgressBarTexture(\"%s\", %s)\n", tostring(opts.ProgressBarData[1]), tostring(opts.ProgressBarData[2])) 1129 | end 1130 | 1131 | if nil ~= opts.DisplayState then 1132 | if obj:isBright() ~= opts.DisplayState then 1133 | self:writef(" obj:setBright(%s)\n", tostring(opts.DisplayState)) 1134 | end 1135 | 1136 | if obj:isEnabled() ~= opts.DisplayState then 1137 | self:writef(" obj:setEnabled(%s)\n", tostring(opts.DisplayState)) 1138 | end 1139 | end 1140 | end 1141 | 1142 | --///////////////////////////////////////////////////////////////////////////// 1143 | function _M:onProperty_LoadingBar(obj, name, value) 1144 | local opts = self.opts 1145 | 1146 | if name == "ProgressInfo" then 1147 | opts["Percent"] = tonumber(value) or 0 1148 | elseif name == "ProgressType" then 1149 | if value == "Left_To_Right" then 1150 | opts["Direction"] = 0 1151 | else 1152 | opts["Direction"] = 1 1153 | end 1154 | else 1155 | return self:onProperty_Node(obj, name, value) 1156 | end 1157 | 1158 | -- print("onProperty_Slider(" .. name .. ", " .. tostring(value) .. ")") 1159 | return true 1160 | end 1161 | 1162 | function _M:onChildren_LoadingBar(obj, name, c) 1163 | local opts = self.opts 1164 | 1165 | if name == "ImageFileData" then 1166 | local f, t, p = c["@Path"] or "", resourceType(c["@Type"]), c["@Plist"] or "" 1167 | if #p > 0 then 1168 | self:addTexture(t, p) 1169 | else 1170 | self:addTexture(t, f) 1171 | end 1172 | opts[name] = { f, t, p } 1173 | else 1174 | return self:onChildren_Node(obj, name, c) 1175 | end 1176 | 1177 | -- print("onChildren_LoadingBar(" .. name .. ", " .. tostring(opts[name]) .. ")") 1178 | return true 1179 | end 1180 | 1181 | function _M:handleOpts_LoadingBar(obj) 1182 | self:handleOpts_Node(obj) 1183 | 1184 | local opts = self.opts 1185 | 1186 | if opts.Percent and obj:getPercent() ~= opts.Percent then 1187 | self:writef(" obj:setPercent(%s)\n", tostring(opts.Percent)) 1188 | end 1189 | 1190 | if opts.Direction and obj:getDirection() ~= opts.Direction then 1191 | self:writef(" obj:setDirection(%s)\n", tostring(opts.Direction)) 1192 | end 1193 | 1194 | if opts.ImageFileData then 1195 | self:writef(" obj:loadTexture(\"%s\", %s)\n", tostring(opts.ImageFileData[1]), tostring(opts.ImageFileData[2])) 1196 | end 1197 | end 1198 | 1199 | --///////////////////////////////////////////////////////////////////////////// 1200 | function _M:onProperty_Layout(obj, name, value) 1201 | local opts = self.opts 1202 | 1203 | if name == "ClipAble" then 1204 | opts["ClippingEnabled"] = (value == "True") 1205 | elseif name == "ComboBoxIndex" then 1206 | opts["BackGroundColorType"] = tonumber(value) or 0 1207 | elseif name == "BackColorAlpha" then 1208 | opts["BackGroundColorOpacity"] = tonumber(value) or 255 1209 | else 1210 | return self:onProperty_Node(obj, name, value) 1211 | end 1212 | 1213 | -- print("onProperty_Layout(" .. name .. ", " .. value .. ")") 1214 | return true 1215 | end 1216 | 1217 | function _M:onChildren_Layout(obj, name, c) 1218 | local opts = self.opts 1219 | 1220 | if name == "SingleColor" or name == "FirstColor" or name == "EndColor" then 1221 | opts[name] = { 1222 | tonumber(c["@R"]) or 0, tonumber(c["@G"]) or 0, 1223 | tonumber(c["@B"]) or 0, tonumber(c["@A"]) 1224 | } 1225 | elseif name == "ColorVector" then 1226 | opts[name] = { tonumber(c["@ScaleX"]) or 0, tonumber(c["@ScaleY"]) or 1 } 1227 | elseif name == "Size" and opts.Scale9Enabled then 1228 | opts["Scale9Size"] = { tonumber(c["@X"]) or 0, tonumber(c["@Y"]) or 0 } 1229 | else 1230 | return self:onChildren_Node(obj, name, c) 1231 | end 1232 | 1233 | return true 1234 | end 1235 | 1236 | function _M:handleOpts_Layout(obj) 1237 | self:handleOpts_Node(obj) 1238 | 1239 | local opts = self.opts 1240 | 1241 | if opts.FileData then 1242 | if opts.Scale9Enabled then 1243 | local capInsets = string.format("cc.rect(%s, %s, %s, %s)", 1244 | tostring(opts.Scale9OriginX or 0), tostring(opts.Scale9OriginY or 0), 1245 | tostring(opts.Scale9Width or 0), tostring(opts.Scale9Height or 0)) 1246 | self:writef(" setBgImage(obj, \"%s\", %s, true, %s)\n", tostring(opts.FileData[1]), tostring(opts.FileData[2]), capInsets) 1247 | 1248 | if opts.Scale9Size then 1249 | self:writef(" obj:setContentSize(%s)\n", formatSize(opts.Scale9Size)) 1250 | end 1251 | else 1252 | self:writef(" obj:setBackGroundImage(\"%s\", %s)\n", tostring(opts.FileData[1]), tostring(opts.FileData[2])) 1253 | end 1254 | end 1255 | 1256 | if nil ~= opts.ClippingEnabled and obj:isClippingEnabled() ~= opts.ClippingEnabled then 1257 | self:write(" obj:setClippingEnabled(" .. tostring(opts.ClippingEnabled) .. ")\n") 1258 | end 1259 | 1260 | if nil ~= opts.BackGroundColorType and opts.BackGroundColorType ~= 0 then 1261 | local bgType, bgOpacity, bgColor, startColor, endColor, colorVec 1262 | 1263 | if obj:getBackGroundColorType() ~= opts.BackGroundColorType then 1264 | bgType = opts.BackGroundColorType 1265 | end 1266 | 1267 | if opts.BackGroundColorType == 1 and opts.SingleColor and 1268 | not isColorEqual(obj:getBackGroundColor(), opts.SingleColor) then 1269 | bgColor = opts.SingleColor 1270 | end 1271 | 1272 | if opts.BackGroundColorType == 2 and opts.FirstColor and opts.EndColor and 1273 | not isColorEqual(obj:getBackGroundStartColor(), opts.FirstColor) and 1274 | not isColorEqual(obj:getBackGroundEndColor(), opts.EndColor) then 1275 | startColor = opts.FirstColor 1276 | endColor = opts.EndColor 1277 | end 1278 | 1279 | if opts.BackGroundColorType == 2 and opts.ColorVector and 1280 | not isPointEqual(obj:getBackGroundColorVector(), opts.ColorVector) then 1281 | colorVec = opts.ColorVector 1282 | end 1283 | 1284 | if opts.BackGroundColorOpacity and obj:getBackGroundColorOpacity() ~= opts.BackGroundColorOpacity then 1285 | bgOpacity = opts.BackGroundColorOpacity 1286 | end 1287 | 1288 | self:writef(" setBgColor(obj, %s, %s, %s, %s, %s, %s)\n", 1289 | tostring(bgType), tostring(bgOpacity), formatColor(bgColor), formatColor(startColor), formatColor(endColor), formatPoint(colorVec)) 1290 | end 1291 | end 1292 | 1293 | --///////////////////////////////////////////////////////////////////////////// 1294 | function _M:onProperty_ScrollView(obj, name, value) 1295 | local opts = self.opts 1296 | 1297 | if name == "ScrollDirectionType" then 1298 | if value == "Vertical" then 1299 | opts["ScrollDirection"] = 1 1300 | elseif value == "Horizontal" then 1301 | opts["ScrollDirection"] = 2 1302 | elseif value == "Vertical_Horizontal" then 1303 | opts["ScrollDirection"] = 3 1304 | else 1305 | opts["ScrollDirection"] = tonumber(value) or 0 1306 | end 1307 | elseif name == "IsBounceEnabled" then 1308 | opts["BounceEnabled"] = (value == "True") 1309 | else 1310 | return self:onProperty_Layout(obj, name, value) 1311 | end 1312 | 1313 | -- print("onProperty_ScrollView(" .. name .. ", " .. value .. ")") 1314 | return true 1315 | end 1316 | 1317 | function _M:onChildren_ScrollView(obj, name, c) 1318 | local opts = self.opts 1319 | 1320 | if name == "InnerNodeSize" then 1321 | opts["InnerContainerSize"] = { tonumber(c["@Width"]) or 0, tonumber(c["@Height"]) or 0 } 1322 | else 1323 | return self:onChildren_Layout(obj, name, c) 1324 | end 1325 | 1326 | return true 1327 | end 1328 | 1329 | function _M:handleOpts_ScrollView(obj) 1330 | self:handleOpts_Layout(obj) 1331 | 1332 | local opts = self.opts 1333 | 1334 | if opts.InnerContainerSize and not isSizeEqual(obj:getInnerContainerSize(), opts.InnerContainerSize) then 1335 | self:writef(" obj:setInnerContainerSize(%s)\n", formatSize(opts.InnerContainerSize)) 1336 | end 1337 | 1338 | if opts.ScrollDirection and obj:getDirection() ~= opts.ScrollDirection then 1339 | self:writef(" obj:setDirection(%s)\n", tostring(opts.ScrollDirection)) 1340 | end 1341 | 1342 | if nil ~= opts.BounceEnabled and obj:isBounceEnabled() ~= opts.BounceEnabled then 1343 | self:writef(" obj:setBounceEnabled(%s)\n", tostring(opts.BounceEnabled)) 1344 | end 1345 | end 1346 | 1347 | --///////////////////////////////////////////////////////////////////////////// 1348 | function _M:onProperty_ListView(obj, name, value) 1349 | local opts = self.opts 1350 | 1351 | if name == "ItemMargin" then 1352 | opts["ItemsMargin"] = tonumber(value) or 0 1353 | elseif name == "DirectionType" then 1354 | opts["Gravity"] = value 1355 | elseif name == "VerticalType" then 1356 | if value == "" then 1357 | opts[name] = 3 1358 | elseif value == "Align_Bottom" then 1359 | opts[name] = 4 1360 | elseif value == "Align_VerticalCenter" then 1361 | opts[name] = 5 1362 | else 1363 | opts[name] = tonumber(value) or 3 1364 | end 1365 | elseif name == "HorizontalType" then 1366 | if value == "" then 1367 | opts[name] = 0 1368 | elseif value == "Align_Right" then 1369 | opts[name] = 1 1370 | elseif value == "Align_HorizontalCenter" then 1371 | opts[name] = 2 1372 | else 1373 | opts[name] = tonumber(value) or 0 1374 | end 1375 | else 1376 | return self:onProperty_ScrollView(obj, name, value) 1377 | end 1378 | 1379 | -- print("onProperty_ListView(" .. name .. ", " .. value .. ")") 1380 | return true 1381 | end 1382 | 1383 | function _M:onChildren_ListView(obj, name, c) 1384 | -- nothing to do 1385 | return self:onChildren_ScrollView(obj, name, c) 1386 | end 1387 | 1388 | function _M:handleOpts_ListView(obj) 1389 | local opts = self.opts 1390 | opts.ScrollDirection = nil 1391 | 1392 | self:handleOpts_ScrollView(obj) 1393 | 1394 | if opts.ItemsMargin and obj:getItemsMargin() ~= opts.ItemsMargin then 1395 | self:writef(" obj:setItemsMargin(%d)\n", tonumber(opts.ItemsMargin) or 0) 1396 | end 1397 | 1398 | if opts.VerticalType or opts.HorizontalType then 1399 | if nil == opts.Gravity or opts.Gravity == "" then 1400 | self:write(" obj:setDirection(2)\n") 1401 | self:writef(" obj:setGravity(%d)\n", tonumber(opts.VerticalType) or 0) 1402 | elseif opts.Gravity == "Vertical" then 1403 | self:write(" obj:setDirection(1)\n") 1404 | self:writef(" obj:setGravity(%d)\n", tonumber(opts.HorizontalType) or 0) 1405 | end 1406 | end 1407 | end 1408 | 1409 | --///////////////////////////////////////////////////////////////////////////// 1410 | function _M:onProperty_PageView(obj, name, value) 1411 | local opts = self.opts 1412 | 1413 | if name == "ScrollDirectionType" then 1414 | -- nothing to do 1415 | else 1416 | return self:onProperty_Layout(obj, name, value) 1417 | end 1418 | 1419 | -- print("onProperty_PageView(" .. name .. ", " .. value .. ")") 1420 | return true 1421 | end 1422 | 1423 | function _M:onChildren_PageView(obj, name, c) 1424 | -- nothing to do 1425 | return self:onChildren_Layout(obj, name, c) 1426 | end 1427 | 1428 | function _M:handleOpts_PageView(obj) 1429 | self:handleOpts_Layout(obj) 1430 | -- nothing to do 1431 | end 1432 | 1433 | --///////////////////////////////////////////////////////////////////////////// 1434 | function _M:readNodeProperties(root, obj, className) 1435 | -- print("readNodeProperties(" .. className .. ")") 1436 | 1437 | local opts = self.opts 1438 | local lays = self.lays 1439 | 1440 | local onProperty = self["onProperty_" .. className] or self.onProperty_Node 1441 | 1442 | for _, p in pairs(root:properties()) do 1443 | local name = p.name 1444 | local value = p.value 1445 | 1446 | if not onProperty(self, obj, name, value) then 1447 | if name ~= "IconVisible" and name ~= "ctype" and name ~= "ActionTag" and name ~= "ColorAngle" and name ~= "CanEdit" and 1448 | name ~= "LeftEage" and name ~= "TopEage" and name ~= "RightEage" and name ~= "BottomEage" then 1449 | print("@@ Nothing to do: readNodeProperties(" .. name .. " @" .. className .. ")") 1450 | end 1451 | end 1452 | end 1453 | end 1454 | 1455 | --///////////////////////////////////////////////////////////////////////////// 1456 | function _M:readNodeChildren(root, obj, className) 1457 | local onChildren = self["onChildren_" .. className] or self.onChildren_Node 1458 | 1459 | for _, c in pairs(root:children()) do 1460 | local name = c:name() 1461 | 1462 | if not onChildren(self, obj, name, c) then 1463 | if name ~= "Children" then 1464 | print("@@ Nothing to do: readNodeChildren(" .. name .. " @" .. className .. ")") 1465 | end 1466 | end 1467 | end 1468 | end 1469 | 1470 | --///////////////////////////////////////////////////////////////////////////// 1471 | function _M:handleNodeOpts(root, obj, className) 1472 | local handleOpts = self["handleOpts_" .. className] or self.handleOpts_Node 1473 | 1474 | local opts = self.opts 1475 | local lays = self.lays 1476 | 1477 | if type(obj.ignoreContentAdaptWithSize) == "function" then 1478 | if (opts.IsCustomSize or lays.PercentWidthEnabled or lays.PercentHeightEnabled or opts.Scale9Enabled) 1479 | and obj:isIgnoreContentAdaptWithSize() then 1480 | opts["IgnoreContentAdaptWithSize"] = false 1481 | end 1482 | end 1483 | 1484 | handleOpts(self, obj) 1485 | end 1486 | 1487 | --///////////////////////////////////////////////////////////////////////////// 1488 | function _M:handleNodeLays(root, obj, className) 1489 | local lays = self.lays 1490 | 1491 | local lay = obj:getComponent("__ui_layout") or ccui.LayoutComponent:create() 1492 | 1493 | for name, value in pairs(lays) do 1494 | if ((type(lay["get" .. name]) == "function" and lay["get" .. name](lay) == value) or 1495 | (type(lay["is" .. name]) == "function" and lay["is" .. name](lay) == value)) then 1496 | lays[name] = nil 1497 | end 1498 | end 1499 | 1500 | local margins, sizes, positions, stretchs, edges = "", "", "", "", "" 1501 | if nil ~= lays.LeftMargin or nil ~= lays.TopMargin or 1502 | nil ~= lays.RightMargin or nil ~= lays.BottomMargin then 1503 | margins = string.format(".setMargin(%s, %s, %s, %s)", 1504 | tostring(lays.LeftMargin), tostring(lays.TopMargin), 1505 | tostring(lays.RightMargin), tostring(lays.BottomMargin)) 1506 | end 1507 | if (nil ~= lays.PercentWidth or nil ~= lays.PercentHeight) and 1508 | (nil ~= lays.PercentWidthEnabled or nil ~= lays.PercentHeightEnabled) then 1509 | sizes = string.format(".setSize(%s, %s, %s, %s)", 1510 | tostring(lays.PercentWidth), tostring(lays.PercentHeight), 1511 | tostring(lays.PercentWidthEnabled), tostring(lays.PercentHeightEnabled)) 1512 | end 1513 | if (nil ~= lays.PositionPercentX or nil ~= lays.PositionPercentY) and 1514 | (nil ~= lays.PositionPercentXEnabled or nil ~= lays.PositionPercentYEnabled) then 1515 | positions = string.format(".setPosition(%s, %s, %s, %s)", 1516 | tostring(lays.PositionPercentX), tostring(lays.PositionPercentY), 1517 | tostring(lays.PositionPercentXEnabled), tostring(lays.PositionPercentYEnabled)) 1518 | end 1519 | if nil ~= lays.StretchWidthEnable or nil ~= lays.StretchHeightEnable then 1520 | stretchs = string.format(".setStretch(%s, %s)", 1521 | tostring(lays.StretchWidthEnable), tostring(lays.StretchHeightEnable)) 1522 | end 1523 | if nil ~= lays.HorizontalEdge or nil ~= lays.VerticalEdge then 1524 | edges = string.format(".setEdge(%s, %s)", 1525 | tostring(lays.HorizontalEdge), tostring(lays.VerticalEdge)) 1526 | end 1527 | 1528 | if #margins > 0 or #sizes > 0 or #positions > 0 or #stretchs > 0 or #edges > 0 then 1529 | self:writef(" bind(obj)%s%s%s%s%s\n", margins, sizes, positions, stretchs, edges) 1530 | end 1531 | end 1532 | 1533 | --///////////////////////////////////////////////////////////////////////////// 1534 | function _M:parseNodeXml(root, obj, className) 1535 | -- print("parseNodeXml(className=" .. className .. ")") 1536 | 1537 | self.opts = {} 1538 | self.lays = {} 1539 | 1540 | self:readNodeProperties(root, obj, className) 1541 | self:readNodeChildren(root, obj, className) 1542 | 1543 | self:handleNodeOpts(root, obj, className) 1544 | self:handleNodeLays(root, obj, className) 1545 | 1546 | return self.opts.Name or "" 1547 | end 1548 | 1549 | --///////////////////////////////////////////////////////////////////////////// 1550 | function _M:objScriptOf(className, root) 1551 | local obj, script = nil, nil 1552 | if className == "ProjectNode" then 1553 | local fileData = root["FileData"] 1554 | if fileData and fileData["@Path"] then 1555 | local path = string.gsub(fileData["@Path"], ".csd", ".lua") 1556 | obj = cc.Node:create() 1557 | script = string.format(" inc = require(\"%s\").create(callBackProvider)\n", path) 1558 | script = script .. " if inc.animation then inc.root:runAction(inc.animation) end\n" 1559 | script = script .. " obj = inc.root\n" 1560 | end 1561 | elseif className == "GameNode" or className == "SingleNode" or className == "Node" then 1562 | obj = cc.Node:create() 1563 | script = " obj = cc.Node:create()\n" 1564 | elseif className == "SimpleAudio" then 1565 | -- reader = ComAudioReader::getInstance(); 1566 | elseif className == "Panel" or className == "Layout" then 1567 | className = "Layout" 1568 | obj = ccui.Layout:create() 1569 | script = " obj = ccui.Layout:create()\n" 1570 | elseif className == "TextButton" or className == "Button" then 1571 | className = "Button" 1572 | obj = ccui.Button:create() 1573 | script = " obj = ccui.Button:create()\n" 1574 | elseif className == "TextArea" or className == "Text" or className == "Label" then 1575 | className = "Text" 1576 | obj = ccui.Text:create() 1577 | script = " obj = ccui.Text:create()\n" 1578 | elseif className == "ImageView" then 1579 | obj = ccui.ImageView:create() 1580 | script = " obj = ccui.ImageView:create()\n" 1581 | elseif className == "RichTextEx" then 1582 | obj = require("ccext.RichTextEx"):create() 1583 | script = " obj = require(\"ccext.RichTextEx\"):create()\n" 1584 | elseif className == "UrlButton" then 1585 | className = "Button" 1586 | obj = require("ccext.UrlButton"):create() 1587 | script = " obj = require(\"ccext.UrlButton\"):create()\n" 1588 | elseif className == "UrlImgView" or className == "UrlImageView" then 1589 | className = "ImageView" 1590 | obj = require("ccext.UrlImgView"):create() 1591 | script = " obj = require(\"ccext.UrlImgView\"):create()\n" 1592 | elseif className == "EditBox" then 1593 | local c, siz = root["Size"], { 100, 32 } 1594 | if c then 1595 | siz = { tonumber(c["@X"]) or 0, tonumber(c["@Y"]) or 0 } 1596 | end 1597 | 1598 | obj = ccui.EditBox:create(cc.size(siz[1], siz[2]), cc.Scale9Sprite:create()) 1599 | script = " obj = ccui.EditBox:create(" .. formatSize(siz) .. ", cc.Scale9Sprite:create())\n" 1600 | elseif className == "TextField" then 1601 | obj = ccui.TextField:create() 1602 | script = " obj = ccui.TextField:create()\n" 1603 | elseif className == "LabelAtlas" or className == "TextAtlas" then 1604 | className = "TextAtlas" 1605 | obj = ccui.TextAtlas:create() 1606 | script = " obj = ccui.TextAtlas:create()\n" 1607 | elseif className == "LabelBMFont" or className == "TextBMFont" then 1608 | className = "TextBMFont" 1609 | obj = ccui.TextBMFont:create() 1610 | script = " obj = ccui.TextBMFont:create()\n" 1611 | elseif className == "Slider" then 1612 | obj = ccui.Slider:create() 1613 | script = " obj = ccui.Slider:create()\n" 1614 | elseif className == "LoadingBar" then 1615 | obj = ccui.LoadingBar:create() 1616 | script = " obj = ccui.LoadingBar:create()\n" 1617 | elseif className == "Sprite" then 1618 | obj = cc.Sprite:create() 1619 | script = " obj = cc.Sprite:create()\n" 1620 | elseif className == "CheckBox" then 1621 | obj = ccui.CheckBox:create() 1622 | script = " obj = ccui.CheckBox:create()\n" 1623 | elseif className == "ScrollView" then 1624 | obj = ccui.ScrollView:create() 1625 | script = " obj = ccui.ScrollView:create()\n" 1626 | elseif className == "ListView" then 1627 | obj = ccui.ListView:create() 1628 | script = " obj = ccui.ListView:create()\n" 1629 | elseif className == "PageView" then 1630 | obj = ccui.PageView:create() 1631 | script = " obj = ccui.PageView:create()\n" 1632 | elseif className == "Particle" then 1633 | local fileData = root["FileData"] 1634 | if fileData and fileData["@Path"] then 1635 | obj = cc.ParticleSystemQuad:create() 1636 | script = string.format(" obj = cc.ParticleSystemQuad:create(\"%s\")\n", fileData["@Path"]) 1637 | end 1638 | elseif className == "GameMap" then 1639 | className = "TMXTiledMap" 1640 | local fileData = root["FileData"] 1641 | if fileData and fileData["@Path"] then 1642 | -- obj = cc.TMXTiledMap:create(fileData["@Path"]) 1643 | obj = cc.Node:create() 1644 | script = string.format(" obj = cc.TMXTiledMap:create(\"%s\")\n", fileData["@Path"]) 1645 | end 1646 | elseif className == "ArmatureNode" then 1647 | className = "Armature" 1648 | obj = ccs.Armature:create() 1649 | script = " obj = ccs.Armature:create()\n" 1650 | elseif className == "SimpleAudio" then 1651 | end 1652 | 1653 | return obj, script, className 1654 | end 1655 | 1656 | --///////////////////////////////////////////////////////////////////////////// 1657 | local _createNodeTree, _i = nil, 0 1658 | _createNodeTree = function(self, root, classType, rootName, rootClassName) 1659 | local pos = string.find(classType, "ObjectData") 1660 | if pos then 1661 | classType = string.sub(classType, 1, pos - 1) 1662 | end 1663 | 1664 | local obj, script, className = self:objScriptOf(classType, root) 1665 | if not obj or not script then return end 1666 | 1667 | self:write(script) 1668 | 1669 | if rootName then 1670 | if rootClassName == "PageView" and className == "Layout" then 1671 | self:write(" " .. rootName .. ":addPage(obj)\n") 1672 | elseif rootClassName == "ListView" then 1673 | self:write(" " .. rootName .. ":pushBackCustomItem(obj)\n") 1674 | else 1675 | self:write(" " .. rootName .. ":addChild(obj)\n") 1676 | end 1677 | else 1678 | self:write(" roots.root = obj\n") 1679 | end 1680 | 1681 | rootName = self:parseNodeXml(root, obj, className) 1682 | rootName = "roots." .. rootName .. "_" .. tostring(_i) 1683 | rootClassName = className 1684 | 1685 | _i = _i + 1 1686 | if root.Children then 1687 | local nextSiblingNode = nextSiblingIter(root.Children) 1688 | local node, udata = nextSiblingNode() 1689 | 1690 | self:write(" " .. rootName .. " = obj\n\n") 1691 | while node do 1692 | className = node["@ctype"] or "NodeObjectData" 1693 | 1694 | udata = node["@UserData"] 1695 | if udata then 1696 | local pos = string.find(udata, "@class_", 1, true) 1697 | if pos then 1698 | className = string.sub(udata, pos + 7) -- .. "ObjectData" 1699 | end 1700 | end 1701 | 1702 | _createNodeTree(self, node, className, rootName, rootClassName) 1703 | node = nextSiblingNode() 1704 | end 1705 | else 1706 | self:write("\n") 1707 | end 1708 | _i = _i - 1 1709 | end 1710 | 1711 | --///////////////////////////////////////////////////////////////////////////// 1712 | function _M:createNodeTree(root, classType) 1713 | return _createNodeTree(self, root, classType) 1714 | end 1715 | 1716 | --///////////////////////////////////////////////////////////////////////////// 1717 | function _M:write(s) 1718 | self._file:write(s) 1719 | end 1720 | 1721 | --///////////////////////////////////////////////////////////////////////////// 1722 | function _M:writef(fmt, ...) 1723 | self:write(string.format(fmt, ...)) 1724 | end 1725 | 1726 | --///////////////////////////////////////////////////////////////////////////// 1727 | function _M:addTexture(t, texture) 1728 | if not self._textures then 1729 | self._textures = {} 1730 | end 1731 | for _, value in pairs(self._textures) do 1732 | if value == texture then return end 1733 | end 1734 | table.insert(self._textures, texture) 1735 | if t == 1 then 1736 | self:write(" ccspc:addSpriteFrames(\"" .. texture .. "\")\n") 1737 | end 1738 | end 1739 | 1740 | --///////////////////////////////////////////////////////////////////////////// 1741 | function _M:csd2lua(csdFile, luaFile) 1742 | local xml = require("ccext.XmlParser").newParser():loadFile(csdFile) 1743 | 1744 | if not xml or xml:numChildren() ~= 1 then 1745 | error("XmlParser:loadFile(" .. csdFile .. ") bad XML.") 1746 | return 1747 | end 1748 | 1749 | local nextSiblingNode = nextSiblingIter(xml:children()[1]) 1750 | local node, name, serializeEnabled = nextSiblingNode(), nil, false 1751 | 1752 | while node do 1753 | name = node:name() 1754 | 1755 | if name == "PropertyGroup" then 1756 | self._csdVersion = node["@Version"] or "2.1.0.0" 1757 | elseif name == "Content" and node:numProperties() == 0 then 1758 | serializeEnabled = true 1759 | break 1760 | end 1761 | 1762 | if node:numChildren() > 0 then 1763 | nextSiblingNode = nextSiblingIter(node) 1764 | node = nextSiblingNode() 1765 | else 1766 | node = nextSiblingNode() 1767 | end 1768 | end 1769 | 1770 | if not serializeEnabled then 1771 | error("serializeEnabled == false") 1772 | return 1773 | end 1774 | 1775 | local file, err = io.open(luaFile, "w+"); 1776 | 1777 | if file and not err then 1778 | self._file = file 1779 | else 1780 | print(err) 1781 | return 1782 | end 1783 | 1784 | self:write(_SCRIPT_HELPER) 1785 | self:write(string.format(_SCRIPT_HEAD, self._csdVersion or "")) 1786 | self:write(_CREATE_FUNC_HEAD) 1787 | 1788 | local tblAni = {} 1789 | 1790 | nextSiblingNode = nextSiblingIter(node) 1791 | node = nextSiblingNode() 1792 | while node do 1793 | name = node:name() 1794 | 1795 | if name == "Animation" then 1796 | table.insert(tblAni, " obj = ccs.ActionTimeline:create()\n") 1797 | table.insert(tblAni, string.format(" obj:setDuration(%d)\n", tonumber(node["@Duration"]) or 0)) 1798 | table.insert(tblAni, string.format(" obj:setTimeSpeed(%d)\n", tonumber(node["@Speed"]) or 1)) 1799 | table.insert(tblAni, " roots.animation = obj\n\n") 1800 | elseif name == "ObjectData" then 1801 | self:createNodeTree(node, "NodeObjectData") 1802 | elseif name == "AnimationList" then 1803 | -- TODO. 1804 | end 1805 | 1806 | node = nextSiblingNode() 1807 | end 1808 | 1809 | if #tblAni > 0 then 1810 | self:write(table.concat(tblAni)) 1811 | end 1812 | 1813 | self:write(_CREATE_FUNC_FOOT) 1814 | 1815 | self:write("_M.textures = {\n") 1816 | for _, v in pairs(self._textures or {}) do 1817 | self:write(" \"" .. v .. "\",\n") 1818 | end 1819 | self:write("}\n") 1820 | 1821 | self:write(_SCRIPT_FOOT) 1822 | 1823 | io.close(file) 1824 | end 1825 | 1826 | --///////////////////////////////////////////////////////////////////////////// 1827 | 1828 | return _M 1829 | -------------------------------------------------------------------------------- /main.lua: -------------------------------------------------------------------------------- 1 | 2 | cc.FileUtils:getInstance():setPopupNotify(false) 3 | cc.FileUtils:getInstance():addSearchPath("src/") 4 | cc.FileUtils:getInstance():addSearchPath("res/") 5 | 6 | require "config" 7 | require "cocos.init" 8 | 9 | local function main() 10 | require("ConvertCSD").doConvert() 11 | 12 | -- Your codes 13 | -- ... 14 | end 15 | 16 | local status, msg = xpcall(main, __G__TRACKBACK__) 17 | if not status then 18 | print(msg) 19 | end 20 | --------------------------------------------------------------------------------