找回密码
 立即注册
查看: 2|回复: 0

TXT组件 Lua代码

[复制链接]

316

主题

66

回帖

1426

积分

积分
1426
发表于 2025-6-25 04:43:22 | 显示全部楼层 |阅读模式
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------
local SUILoader = class("SUILoader")

local Element       = require("sui/Element")
local SWidget       = require("sui/SWidget")
local SUIHelper     = require("sui/SUIHelper")
local LexicalHelper = require("sui/LexicalHelper")
local RichTextHelp  = require("util/RichTextHelp")
local QuickCell     = requireUtil("QuickCell")
local cjson         = require("cjson")

local tinsert       = table.insert
local tremove       = table.remove
local ssplit        = string.split
local sfind         = string.find

local mfloor        = math.floor

local DEBUG_MODE    = false

------------------------------------------ util
SUILoader.convertToDesignPos = function(swidget, input_pos)
    local parent        = swidget.render:getParent()
    local visibleSize   = global.Director:getVisibleSize()
    local parentSize    = parent and parent:getContentSize() or visibleSize

    local x             = tonumber(input_pos.x) or 0
    local y             = tonumber(input_pos.y) or 0
    local fixX          = x
    local fixY          = parentSize.height-y
   
    return cc.p(fixX, fixY)
end

SUILoader.convertToOpenGLPos = function(swidget, input_pos)
    local parent        = swidget.render:getParent()
    local visibleSize   = global.Director:getVisibleSize()
    local parentSize    = parent and parent:getContentSize() or visibleSize

    local x             = tonumber(input_pos.x) or 0
    local y             = tonumber(input_pos.y) or 0
    local fixX          = x
    local fixY          = parentSize.height-y
   
    return cc.p(fixX, fixY)
end

SUILoader.compareSWidget = function(a, b)
    if not a or not b then
        return 0
    end
    if #a.branches ~= #b.branches then
        return -5
    end

    local eleA = a.element
    local eleB = b.element
    if not eleA or not eleB then
        return -1
    end

    -- 类型不同
    if eleA.type ~= eleB.type then
        return -2
    end

    -- 重新加载
    local reloadA   = tonumber(eleA.attr.reload) or 0
    local reloadB   = tonumber(eleB.attr.reload) or 0
    if reloadB == 1 then
        return -6
    end
    if eleA.type == "Frames" then
        return -6
    end
    if eleA.type == "Effect" and (eleA.attr.count == 1 or eleB.attr.count == 1) then
        return -6
    end
    if eleA.type == "CheckBox" then
        return -6
    end
    if eleA.type == "COUNTDOWN" then
        return -6
    end
    if eleA.type == "BAGITEMS" or eleA.type == "HEROBAGITEMS" or eleA.type == "DLINKITEMS" then
        return -6
    end
    if eleA.type == "EQUIPITEMS" or eleA.type == "HEROEQUIPITEMS" then
        return -6
    end
    if eleA.type == "DBItemShow" or eleA.type == "HERODBItemShow" or eleA.type == "MKItemShow" then
        return -6
    end
    if eleA.type == "Input" then
        return -6
    end
    if eleA.type == "TIMETIPS" then
        return -6
    end
    if eleA.type == "LoadingBar" then
        return -6
    end
    if eleA.type == "Slider" then
        return -6
    end
    if eleA.type == "MenuItem" then
        return -6
    end
    if eleA.type == "ScrapePic" then
        return -6
    end

    local ignored   = {[1]="id", [2]="default", [3]="reload", [4]="loadCount", [5]="loadDelay", [6]="loadStep", [7]="tax", [8]="tay", [9]="tpercentx", [10]="tpercenty"}
    local attrA     = clone(eleA.attr)
    local attrB     = clone(eleB.attr)
    for _, v in ipairs(ignored) do
        attrA[v] = nil
        attrB[v] = nil
    end
    for key, value in pairs(attrA) do
        if not attrB[key] then
            -- 属性数量不同
            return -3
        end
        if value ~= attrB[key] then
            -- 属性值不同
            return -4
        end
        attrB[key] = nil
    end
    if next(attrB) then
        -- 属性数量不同
        return -3
    end

    -- 属性相同
    return 1
end

SUILoader.isBackground = function(swidget)
    if not swidget then
        return false
    end
    return tonumber(swidget.element.attr.bg) == 1
end
------------------------------------------
------------------------------------------

--
local defaultOutline    = 1
local defaultOutlineC   = 0
local defaultColorID    = 255
local defaultFontSize   = global.isWinPlayMode and 12 or 18
local anchorPoints      = {[0]={x=0,y=1}, [1]={x=1,y=1}, [2]={x=0,y=0}, [3]={x=1,y=0}, [4]={x=0.5,y=0.5}}
local defaultTextX      = 25
local defaultTextY      = 20
local interval          = 0.167
local defaultFontPath   = SL:GetMetaValue("GAME_DATA", "SUI_FONT_PATH") or global.MMO.PATH_FONT2

SUILoader.getAnchorByIndex = function(index)
    return anchorPoints[index or 0]
end

SUILoader.modifySizeAble = function(swidget)
    local element = swidget.element
    if element.type == "Effect" then
        return false
    end
    if element.type == "Text" then
        return false
    end
    if element.type == "ItemShow" then
        return false
    end
    if element.type == "CostItem" then
        return false
    end
    if element.type == "COUNTDOWN" then
        return false
    end
    if element.type == "EquipShow" or element.type == "HEROEquipShow" or element.type == "PETEQUIPSHOW" then
        return false
    end
    if element.type == "TIMETIPS" then
        return false
    end
    if element.type == "TextAtlas" then
        return false
    end
    if element.type == "UIModel" then
        return false
    end
    if element.type == "ScrapePic" then
        return false
    end
    if element.type == "BmpText" then
        return false
    end
    return true
end

SUILoader.modifyAnchorAble = function(swidget)
    local element = swidget.element
    if element.type == "Effect" then
        return false
    end
    if element.type == "UIModel" then
        return false
    end
    return true
end

SUILoader.modifyRotateAble = function(swidget)
    return true
end

SUILoader.modifyVisible = function(swidget)
    return true
end

SUILoader.modifyOpacity = function(swidget)
    local element = swidget.element
    if element.type == "CostItem" then
        return false
    end
    if element.type == "QuickTextView" then
        return false
    end
    if element.type == "ItemShow" or element.type == "DBItemShow" or element.type == "HERODBItemShow" or element.type == "MKItemShow" then
        return false
    end
    if element.type == "EquipShow" or element.type == "HEROEquipShow" or element.type == "PETEQUIPSHOW" then
        return false
    end
    return true
end

SUILoader.fixAnchor = function(swidget)
    if tonumber(swidget.element.attr.bg) == 1 and (tonumber(swidget.element.attr.show) == 5 or tonumber(swidget.element.attr.show) == 6) then
        local ax            = tonumber(swidget.element.attr.tax)
        local ay            = tonumber(swidget.element.attr.tay)
        ax                  = ax or 0
        ay                  = ay or 1
        return cc.p(ax, ay)
    end
    if swidget.element.attr.ax or swidget.element.attr.ay then
        local ax            = tonumber(swidget.element.attr.ax)
        local ay            = tonumber(swidget.element.attr.ay)
        ax                  = ax or 0
        ay                  = ay or 1
        return cc.p(ax, ay)
    end

    local a                 = tonumber(swidget.element.attr.a) or 0
    return SUILoader.getAnchorByIndex(a)
end

SUILoader.fixPosition = function(swidget)
    local parent            = swidget.render:getParent()
    local parentSize        = parent:getContentSize()

    local defaultX          = (swidget.element.type == "Text" or swidget.element.type == "RText" or swidget.element.type == "RTextX" or swidget.element.type == "BmpText") and defaultTextX or 0
    local defaultY          = (swidget.element.type == "Text" or swidget.element.type == "RText" or swidget.element.type == "RTextX" or swidget.element.type == "BmpText") and defaultTextY or 0
    local x                 = tonumber(swidget.element.attr.x) or defaultX
    local y                 = parentSize.height - (tonumber(swidget.element.attr.y) or defaultY)

    local percentx          = nil
    local percenty          = nil
    if tonumber(swidget.element.attr.bg) == 1 and (tonumber(swidget.element.attr.show) == 5 or tonumber(swidget.element.attr.show) == 6) then
        percentx            = tonumber(swidget.element.attr.tpercentx)
        percenty            = tonumber(swidget.element.attr.tpercenty)
    else
        percentx            = tonumber(swidget.element.attr.percentx)
        percenty            = tonumber(swidget.element.attr.percenty)
    end
    if percentx then
        x                   = parentSize.width * (percentx/100)
    end
    if percenty then
        y                   = parentSize.height - parentSize.height * (percenty/100)
    end

    return cc.p(x, y)
end

SUILoader.fixSize = function(swidget)
    local parent            = swidget.render:getParent()
    local parentSize        = parent:getContentSize()

    local contentSize       = swidget.render:getContentSize()
    local defaultWidth      = contentSize.width
    local defaultHeight     = contentSize.height
    local width             = tonumber(swidget.element.attr.width) or defaultWidth
    local height            = tonumber(swidget.element.attr.height) or defaultHeight

    local percentwidth      = tonumber(swidget.element.attr.percentwidth)
    local percentheight     = tonumber(swidget.element.attr.percentheight)
    if percentwidth then
        width               = parentSize.width * (percentwidth/100)
    end
    if percentheight then
        height              = parentSize.height * (percentheight/100)
    end
   
    return cc.size(width, height)
end

SUILoader.fixRotate = function(swidget)
    local rotate            = tonumber(swidget.element.attr.rotate) or 0
    return rotate
end

SUILoader.fixVisible = function(swidget)
    -- 默认0可见 1不可见
    local visible           = tonumber(swidget.element.attr.visible) or 0
    return visible == 0
end

SUILoader.fixOpacity = function(swidget)
    -- 默认不透明度 255
    local opacity           = tonumber(swidget.element.attr.opacity) or 255
    return opacity
end

-- load attr
SUILoader.loadSWidgetAttr = function(swidget)
    local render    = swidget.render
    local element   = swidget.element

    -- size
    if SUILoader.modifySizeAble(swidget) then
        local size      = SUILoader.fixSize(swidget)
        render:ignoreContentAdaptWithSize(false)
        render:setContentSize(size)
    end

    -- anchor
    if SUILoader.modifyAnchorAble(swidget) then
        local anchor    = SUILoader.fixAnchor(swidget)
        render:setAnchorPoint(anchor)
    end

    -- rotate
    if SUILoader.modifyRotateAble(swidget) then
        local rotate    = SUILoader.fixRotate(swidget)
        render:setRotation(rotate)
    end

    -- x y
    local position  = SUILoader.fixPosition(swidget)
    render:setPosition(position)
    local worldPos = render:convertToWorldSpace(cc.p(0, 0))
    local tranPos =  cc.p(mfloor(worldPos.x), mfloor(worldPos.y))
    render:setPosition(cc.pAdd(position, cc.pSub(tranPos, worldPos)))

    if SUILoader.modifyVisible(swidget) then
        local visible = SUILoader.fixVisible(swidget)
        render:setVisible(visible)
    end

    if SUILoader.modifyOpacity(swidget) then
        local opacity = SUILoader.fixOpacity(swidget)
        if render.setOpacity then
            render:setOpacity(opacity)
        end
    end

end


------------------------------------------
--- SUILoad Core
function SUILoader:ctor()
    defaultOutline = SL:GetMetaValue("GAME_DATA","defaultOutlineSize") or 0
    defaultOutlineC = SL:GetMetaValue("GAME_DATA","defaultOutlineColor") or 0
end

function SUILoader:getInputTable(fliter)
    local submitTable = {}

    if fliter == nil or fliter == "" or fliter == "0" then
    elseif fliter == "*" then
        for k, v in pairs(self._inputWidgets) do
            local input      = v
            local inputID    = k
            local inputValue = input.widget and input.widget:getString() or ""
            table.insert(submitTable, {id = inputID, value = inputValue, type = input.inputFlag, isChatInput = input.isChatInput, isNameInput = input.isNameInput})
        end
    else
        local slices = ssplit(fliter, ",")
        for i, v in ipairs(slices) do
            local inputID    = v
            local input      = self._inputWidgets[inputID]
            local inputValue = input.widget and input.widget:getString() or ""
            table.insert(submitTable, {id = inputID, value = inputValue, type = input.inputFlag, isChatInput = input.isChatInput, isNameInput = input.isNameInput})
        end
    end
    return submitTable
end

function SUILoader:getCheckBoxTable(fliter)
    local submitTable = {}

    if fliter == nil or fliter == "" or fliter == "0" then
        submitTable  = {}
    else
        for k, v in pairs(self._checkboxWidgets) do
            local widget     = v
            local widgetID   = k
            local value      = (widget:isSelected() and 1 or 0)
            table.insert(submitTable, {id = widgetID, value = value})
        end
    end
    return submitTable
end

function SUILoader:getCheckBoxTableByID(widgetID)
    local submitTable = {}

    local widget = self._checkboxWidgets[widgetID]
    if not widget then
        submitTable = {}
    else
        local value = (widget:isSelected() and 1 or 0)
        table.insert(submitTable, {id = widgetID, value = value})
    end
    return submitTable
end

function SUILoader:getSliderTableByID(widgetID)
    local submitTable = {}

    local param = self._sliderWidgets[widgetID]
    if not param or not param.widget then
        submitTable = {}
    else
        local value = param and param.value or 0
        table.insert(submitTable, {id = widgetID, value = value})
    end
    return submitTable
end

function SUILoader:getMenuItemTableByID(widgetID)
    local submitTable = {}

    local param = self._menuItemWidgets[widgetID]
    if not param or not param.widget then
        submitTable = {}
    else
        local value = param and param.value or ""
        value = param.widget:getString() or ""
        table.insert(submitTable, {id = widgetID, value = value})
    end
    return submitTable
end

function SUILoader:addMouseOverTips(widget, element)
    widget:setSwallowMouse(false)
    widget:setMouseEnabled(false)

    local tips              = element.attr.tips
    local tipsx             = tonumber(element.attr.tipsx) or 0
    local tipsy             = tonumber(element.attr.tipsy) or 0

    if tips and string.len(tips) > 0 then
        -- 监听事件;
        tips = string.gsub(tips, "%^", "\\")
        widget:addMouseOverTips(tips, cc.p(tipsx, -tipsy), cc.p(0.5, 1))
    end
end


------------------------------------------------------------------
-- load
function SUILoader:load(source, callback, closeCB, ext)
    local clock             = os.clock()

    -- parse
    local elements = LexicalHelper:Parse(source)

    -- fix background
    self:fixBackground(elements, ext)

    -- content
    local visibleSize       = global.Director:getVisibleSize()
    local _, rootRect       = checkNotchPhone()
    rootRect.width          = visibleSize.width
    rootRect.height         = visibleSize.height
    local trunk, background = self:loadContent(elements, callback, closeCB, rootRect, ext)

    print("load cost", os.clock() - clock)

    return trunk, background
end

function SUILoader:fixBackground(elements, ext)
    -- 优先级 脚本中设置过bg字段 -> GM指定大背景框 -> 默认背景框
    -- dump(elements)
    -- find background
    local background = nil
    for k, v in ipairs(elements) do
        if v.attr["bg"] == "1" then
            if not background then
                background = v
            else
                v.attr["bg"] = nil
            end
        end
    end

    if nil == background then
        if ext and ext.background then
            -- GM指定大背景框
            -- OPENMERCHANTBIGDLG 路径 显示位置  X坐标 Y坐标  高度 宽度 是否显示关闭按钮 关闭按钮X坐标 关闭按钮Y坐标 固定NPC对话框
            if ext.background.Param7 and tonumber(ext.background.Param7) == 1 then
                local element       = {}
                element.type        = "Button"
                element.attr        = {}
                element.attr.nimg   = "public/1900000510.png"  
                element.attr.pimg   = "public/1900000511.png"
                element.attr.link   = "@exit"
                element.attr.x      = tonumber(ext.background.Param8)
                element.attr.y      = tonumber(ext.background.Param9)
                table.insert(elements, 1, element)
            end
            
            local element           = {}
            element.type            = "Img"
            element.attr            = {}
            element.attr.img        = ext.background.Param1
            element.attr.bg         = 1
            element.attr.move       = tonumber(ext.background.Param10) and 1 or 0
            element.attr.reset      = 1
            element.attr.show       = tonumber(ext.background.Param2)
            element.attr.x          = tonumber(ext.background.Param3)
            element.attr.y          = tonumber(ext.background.Param4)
            element.attr.height     = tonumber(ext.background.Param5) ~= 0 and tonumber(ext.background.Param5) or nil
            element.attr.width      = tonumber(ext.background.Param6) ~= 0 and tonumber(ext.background.Param6) or nil
            element.attr.loadDelay  = 1
            table.insert(elements, 1, element)
        else
            -- 默认背景框
            local element           = {}
            element.type            = "Button"
            element.attr            = {}
            element.attr.nimg       = "public/1900000510.png"  
            element.attr.pimg       = "public/1900000511.png"
            element.attr.link       = "@exit"
            element.attr.x          = 546
            element.attr.y          = 0
            table.insert(elements, 1, element)

            local element           = {}
            element.type            = "Layout"
            element.attr            = {}
            element.attr.width      = 80
            element.attr.height     = 80
            element.attr.x          = 545
            element.attr.y          = 0
            element.attr.link       = "@exit"
            table.insert(elements, 1, element)
   
            local element           = {}
            element.type            = "Img"
            element.attr            = {}
            element.attr.img        = SL:GetMetaValue("WINPLAYMODE") and "public_win32/bg_npc_01.png" or "public/bg_npc_01.png"  
            element.attr.bg         = 1
            element.attr.move       = 0
            element.attr.reset      = 1
            element.attr.show       = 0
            element.attr.loadDelay  = 1
            table.insert(elements, 1, element)
        end
    end

    return background
end

function SUILoader:loadContent(elements, callback, closeCB, rootRect, ext)
    self._loaders           =
    {
        ["Img"]             = handler(self, self.load_render_Img),
        ["Text"]            = handler(self, self.load_render_Text),
        ["RText"]           = handler(self, self.load_render_RText),
        ["Input"]           = handler(self, self.load_render_Input),
        ["Button"]          = handler(self, self.load_render_Button),
        ["Effect"]          = handler(self, self.load_render_Effect),
        ["Frames"]          = handler(self, self.load_render_Frames),
        ["Layout"]          = handler(self, self.load_render_Layout),
        ["CheckBox"]        = handler(self, self.load_render_CheckBox),
        ["ListView"]        = handler(self, self.load_render_ListView),
        ["ItemShow"]        = handler(self, self.load_render_ItemShow),
        ["CostItem"]        = handler(self, self.load_render_CostItem),
        ["COUNTDOWN"]       = handler(self, self.load_render_COUNTDOWN),
        ["ITEMBOX"]         = handler(self, self.load_render_ITEMBOX),
        ["EquipShow"]       = handler(self, self.load_render_EquipShow),
        ["BAGITEMS"]        = handler(self, self.load_render_BAGITEMS),
        ["EQUIPITEMS"]      = handler(self, self.load_render_EQUIPITEMS),
        ["DBItemShow"]      = handler(self, self.load_render_DBItemShow),
        ["TIMETIPS"]        = handler(self, self.load_render_TIMETIPS),
        ["TextAtlas"]       = handler(self, self.load_render_TextAtlas),
        ["LoadingBar"]      = handler(self, self.load_render_LoadingBar),
        ["CircleBar"]       = handler(self, self.load_render_CircleBar),
        ["PercentImg"]      = handler(self, self.load_render_PercentImg),
        ["UIModel"]         = handler(self, self.load_render_UIModel),
        ["HEROEquipShow"]   = handler(self, self.load_render_HEROEquipShow),
        ["HEROEQUIPITEMS"]  = handler(self, self.load_render_HEROEQUIPITEMS),
        ["HERODBItemShow"]  = handler(self, self.load_render_HERODBItemShow),
        ["HEROBAGITEMS"]    = handler(self, self.load_render_HEROBAGITEMS),
        ["QuickTextView"]   = handler(self, self.load_render_QuickTextView),
        ["RTextX"]          = handler(self, self.load_render_RTextX),
        ["DLINKITEMS"]      = handler(self, self.load_render_DLINKITEMS),
        ["MKItemShow"]      = handler(self, self.load_render_MKItemShow),
        ["PETEQUIPSHOW"]    = handler(self, self.load_render_PETEQUIPSHOW),
        ["PageView"]        = handler(self, self.load_render_PageView),
        ["Slider"]          = handler(self, self.load_render_Slider),
        ["MenuItem"]        = handler(self, self.load_render_MenuItem),
        ["ScrapePic"]       = handler(self, self.load_render_ScrapePic),
        ["BmpText"]         = handler(self, self.load_render_BmpText),
        ["ButtonKeFu"]      = handler(self, self.load_render_ButtonKeFu),
    }

    --
    self._inputWidgets      = {}
    self._checkboxWidgets   = {}
    self._sliderWidgets     = {}
    self._menuItemWidgets   = {}

    local SUIComponentProxy = global.Facade:retrieveProxy(global.ProxyTable.SUIComponentProxy)

    -- 对比上次,差异化更改
    local lastTrunk             = ext and ext.lastTrunk or nil
    local lastBackground        = ext and ext.lastBackground or nil
    local loadCompleteCB        = ext and ext.loadCompleteCB or nil
    local isImmediate           = ext and ext.isImmediate or false
    local parentNode            = ext and ext.parentNode or nil
    local npcLayer              = ext and ext.npcLayer or nil --刷新npcLayer的background
    if npcLayer then
        SUIComponentProxy:ClearSUISlider()
    end
    -- load swidgets
    local background            = nil
    local swidgets              = {}
    for i, element in ipairs(elements) do
        -- exist loader
        if self._loaders[element.type] then
            element.attr.id     = element.attr.id or string.format("default_%s", i)
            element.attr.x      = (element.type == "Text" or element.type == "RText" or element.type == "RTextX" or element.type == "BmpText") and (element.attr.x or defaultTextX) or element.attr.x
            element.attr.y      = (element.type == "Text" or element.type == "RText" or element.type == "RTextX" or element.type == "BmpText") and (element.attr.y or defaultTextY) or element.attr.y
            element.attr._mainIndex= ext and ext.mainIndex    -- 主界面的按钮/图片点击需上报, 加的标识
            -- swidget
            local swidget       = global.SWidgetCache:generateSWidget()
            swidget.element     = element
            swidget.render      = nil
            swidgets[element.attr.id] = swidget

            -- 记录背景图
            local isBG          = tonumber(element.attr.bg) == 1
            if isBG and not background then
                background      = swidget
            end
        end
    end

    -- tree mode
    for _, element in ipairs(elements) do
        if swidgets[element.attr.id] and swidgets[element.attr.id].element.attr.children then
            local swidget   = swidgets[element.attr.id]
            local branches  = swidget.element.attr.children
            local find_info = {sfind(branches, "{(.-)}")}
            local slices    = ssplit(find_info[3] or branches, ",")
            if #slices > 0 then
                for _, branchID in ipairs(slices) do
                    local branch = swidgets[branchID]
                    if branch and not branch.render and branch.element.attr.id ~= swidget.element.attr.id then
                        if branch.trunk then
                            print("ERROR SUILoader: swidget can't be add aegin. swidgetID=" .. element.attr.id .. "  branchID=" .. branchID)
                        else
                            swidget:addBranch(branch)
                        end
                    end
                end
            end
        end
    end

    -- trunk
    local trunk             = global.SWidgetCache:generateSWidget()
    trunk.element           = Element.new("Layout")
    trunk.depth             = 0
    for _, element in ipairs(elements) do
        local swidget = swidgets[element.attr.id]
        if swidget and swidget.trunk == nil then
            trunk:addBranch(swidget)
        end
    end

    -- compare
    if lastTrunk then
        local backgroundR = SUILoader.compareSWidget(lastBackground, background)
        --
        local function fixBranches(trunkL, trunkC)
            if #trunkL.branches <= 0 then
                if #trunkC.branches > 0 then
                    for index, branch in ipairs(trunkC.branches) do
                        trunkL:addBranch(branch)
                    end
                end
                return nil
            end

            -- 数量不同
            local additions = {}
            if #trunkL.branches < #trunkC.branches then
                for i = #trunkL.branches+1, #trunkC.branches do
                    tinsert(additions, trunkC.branches[i])
                end
            end

            local rmvitemsL     = {}
            local insertitemsL  = {}
            for index, branch in ipairs(trunkL.branches) do
                local branchL   = branch
                local branchC   = trunkC.branches[index]
                local compareR  = SUILoader.compareSWidget(branchL, branchC)

                if compareR == 0 then
                    tinsert(rmvitemsL, branchL)

                elseif compareR == 1 and backgroundR == 1 then
                    if SUILoader.isBackground(branchL) and SUILoader.isBackground(branchC) then
                        background = branchL
                    end
                    local element = branchC.element
                    if element.type == "ListView" and tonumber(element.attr.reload) == 2 then
                        local default       = tonumber(element.attr.default)
                        if branchL.element then
                            branchL.element.attr.default = default
                        end
                    end
                    self:reload_render(branchL)
                    fixBranches(branchL, branchC)

                elseif backgroundR ~= 1 or compareR == -1 or compareR == -2 or compareR == -3 or compareR == -4 or compareR == -5 or compareR == -6 then
                    tinsert(rmvitemsL, branchL)
                    tinsert(insertitemsL, {branch=branchC, index=index})
                end
            end

            for index, branch in ipairs(rmvitemsL) do
                trunkL:removeBranch(branch)
            end
            for index, item in ipairs(insertitemsL) do
                trunkL:insertBranch(item.branch, item.index)
            end
            for index, branch in ipairs(additions) do
                trunkL:addBranch(branch)
            end
        end
        fixBranches(lastTrunk, trunk)

        --
        trunk = lastTrunk
    end


    -- load trunk render
    if trunk and not trunk.render then
        trunk.render        = self:load_render(trunk, callback, closeCB)
    end
    ---
    if parentNode and not trunk.render:getParent() then
        trunk.render:addTo(parentNode)
    end
    -- load background render
    if background and not background.render then
        background.render   = self:load_render(background, callback, closeCB)
        trunk:addBranchRender(background)
    end
    -- size
    if background and background.render and SUILoader.modifySizeAble(background) then
        local size          = SUILoader.fixSize(background)
        background.render:ignoreContentAdaptWithSize(false)
        background.render:setContentSize(size)
    end

    local root_anchor       = cc.p(0, 0)
    local root_position     = cc.p(mfloor(rootRect.x), 0)
    local root_size         = cc.size(rootRect.width, rootRect.height)
    if background then
        local root_show     = tonumber(background.element.attr.show) or 0
        if root_show == 0 then
            -- 左上
            root_anchor     = cc.p(0, 1)
            root_position   = cc.p(mfloor(rootRect.x), rootRect.height)
            root_size       = background.render:getContentSize()

        elseif root_show == 1 then
            -- 右上
            root_anchor     = cc.p(1, 1)
            root_position   = cc.p(rootRect.width, rootRect.height)
            root_size       = background.render:getContentSize()

        elseif root_show == 2 then
            -- 左下
            root_anchor     = cc.p(0, 0)
            root_position   = cc.p(mfloor(rootRect.x), 0)
            root_size       = background.render:getContentSize()

        elseif root_show == 3 then
            -- 右下
            root_anchor     = cc.p(1, 0)
            root_position   = cc.p(rootRect.width, 0)
            root_size       = background.render:getContentSize()

        elseif root_show == 4 then
            -- 中间
            root_anchor     = cc.p(0.5, 0.5)
            root_position   = cc.p(mfloor((rootRect.width)/2), mfloor(rootRect.height/2))
            root_size       = background.render:getContentSize()

            -- 尺寸处理成偶数,防止特效抖动
            root_size = {width = ConvertToEven(root_size.width), height = ConvertToEven(root_size.height)}

        elseif root_show == 5  or root_show == 6 then
            -- 中间铺满
            local attr      = background.element.attr
            root_size       = (attr.width or attr.height) and background.render:getContentSize() or root_size
            root_anchor     = cc.p(0.5, 0.5)
            root_position   = cc.p(mfloor((rootRect.width)/2), mfloor(rootRect.height/2))
            background.element.attr.tax = 0.5
            background.element.attr.tay = 0.5
            background.element.attr.tpercentx = 50
            background.element.attr.tpercenty = 50

            -- 尺寸处理成偶数,防止特效抖动
            root_size = {width = ConvertToEven(root_size.width), height = ConvertToEven(root_size.height)}

        elseif root_show == 7 then
            -- 上下居中
            root_anchor.y   = 0.5
            root_position.y = mfloor(rootRect.height / 2)
            root_size       = background.render:getContentSize()

            -- 尺寸处理成偶数,防止特效抖动
            root_size.height = ConvertToEven(root_size.height)

        elseif root_show == 8 then
            -- 左右居中
            root_anchor.x   = 0.5
            root_position.x = mfloor(rootRect.width / 2)
            root_size       = background.render:getContentSize()
        
            -- 尺寸处理成偶数,防止特效抖动
            root_size.width = ConvertToEven(root_size.width)
        end
    end
    trunk.render:setContentSize(root_size)
    trunk.render:setAnchorPoint(root_anchor)
    trunk.render:setPosition(root_position)
    trunk.render:stopAllActions()

    -- load background attr
    if background and background.render then
        SUILoader.loadSWidgetAttr(background)
    end

    -- DEBUG
    if DEBUG_MODE then
        trunk.render:setBackGroundColor(cc.Color3B.RED)
        trunk.render:setBackGroundColorType(1)
        trunk.render:setBackGroundColorOpacity(80)
    end

    ---------------------------------------
    -- load renders
    local function loadBranchRenders(loadTrunk)
        if #loadTrunk.branches == 0 then
            return nil
        end

        for _, branch in ipairs(loadTrunk.branches) do
            if not branch.render then
                local render = self:load_render(branch, callback, closeCB)
                if render then
                    branch.render = render
   
                    -- add to trunk
                    loadTrunk:addBranchRender(branch)
                    
                    -- load show attr
                    SUILoader.loadSWidgetAttr(branch)
                    if loadTrunk.element.type == "ListView" then
                        if loadTrunk.element.attr.default  and tonumber(loadTrunk.element.attr.default) then
                            local default = tonumber(loadTrunk.element.attr.default) - 1
                            local index = math.max(default, 0)
                            loadTrunk.render:jumpToItem(index, cc.p(0, 0), cc.p(0, 0))
                        end
                        loadTrunk.render:doLayout()
                    end
                    if loadTrunk.element.type == "PageView" then
                        if loadTrunk.element.attr.default  and tonumber(loadTrunk.element.attr.default) then
                            local default = tonumber(loadTrunk.element.attr.default) - 1
                            local index = math.max(default, 0)
                            loadTrunk.render:setCurrentPageIndex(index)
                        end
                        loadTrunk.render:doLayout()
                    end
                end
            end
        end
    end

    -- load immediate flag, edit form background
    local loadCount     = 1
    local loadStep      = 50
    if background then
        if isImmediate == false then
            isImmediate = true
            --
            if tonumber(background.element.attr.loadDelay) == 1 then
                isImmediate = false
            end
        end

        loadCount       = tonumber(background.element.attr.loadCount) or loadCount
        loadStep        = tonumber(background.element.attr.loadStep) or loadStep
        if npcLayer then
            npcLayer.background = background
        end
    end
    if isImmediate then
        local function loadBranch(loadTrunk)
            if #loadTrunk.branches > 0 then
                loadBranchRenders(loadTrunk)

                for _, branch in ipairs(loadTrunk.branches) do
                    loadBranch(branch)
                end
            end
        end
        loadBranch(trunk)

        -- 装载完成
        if loadCompleteCB then
            loadCompleteCB()
        end
    else
        local loadQueue = {}
        local loadTrunk = nil
        tinsert(loadQueue, trunk)
        local function scheduleCB(sender, loadInit)
            local step = loadInit and loadCount or loadStep
            for i=1, step do
                if #loadQueue == 0 then
                    trunk.render:stopAllActions()

                    -- 装载完成
                    if loadCompleteCB then
                        loadCompleteCB()
                    end
                    return
                end

                -- load render
                loadTrunk = tremove(loadQueue, 1)
                loadBranchRenders(loadTrunk)

                if #loadTrunk.branches > 0 then
                    for _, branch in ipairs(loadTrunk.branches) do
                        if #branch.branches > 0 then
                            tinsert(loadQueue, branch)
                        end
                    end
                end
            end
        end
        schedule(trunk.render, scheduleCB, interval)
        scheduleCB(trunk.render, true)
    end

    return trunk, background
end

function SUILoader:load_action(source)
    if not source then
        return nil
    end

    local find_info = {sfind(source, "{(.+)}")}
    if not (find_info[1] and find_info[2] and string.len(find_info[3]) > 0) then
        return nil
    end

    local actions = {}
    local slices  = ssplit(find_info[3], ";")
    for _, slice in ipairs(slices) do
        local slice_info    = {sfind(slice, "(.+):(.+)")}
        local action_type   = tonumber(slice_info[3])
        local params        = ssplit(slice_info[4], "#")
        if action_type == 1 then
            table.insert(actions, cc.ScaleTo:create(tonumber(params[1]), tonumber(params[2]), tonumber(params[2])))
        elseif action_type == 2 then
            dump(params)
            table.insert(actions, cc.FadeTo:create(tonumber(params[1]), tonumber(params[2])))
        end
    end

    if not next(actions) then
        return nil
    end
    return cc.Sequence:create(actions)
end

function SUILoader:reload_render(swidget)
    local element           = swidget.element
    if element.type == "ListView" then
        local default       = tonumber(element.attr.default)
        if default and swidget.render then
            -- default
            local function callback()
                local index = math.max(default - 1, 0)
                swidget.render:jumpToItem(index, cc.p(0, 0), cc.p(0, 0))
                swidget.render:doLayout()
            end
            performWithDelay(swidget.render, callback, 1/60)
        end
    end
    if element.type == "PageView" then
        local default       = tonumber(element.attr.default)
        if default and swidget.render then
            -- default
            local function callback()
                local index = math.max(default - 1, 0)
                swidget.render:setCurrentPageIndex(index)
                swidget.render:doLayout()
            end
            performWithDelay(swidget.render, callback, 1/60)
        end
    end
end

function SUILoader:load_render(swidget, callback, closeCB)
    local element           = swidget.element
    local loader            = self._loaders[element.type]
    if nil == loader then
        print("load render error")
        return nil
    end

    local render            = loader(swidget, callback, closeCB)
    render:setCascadeOpacityEnabled(true)
    render:setName(element.attr.id)
    return render
end

function SUILoader:linkFuncWithCheckWords(callback, param)
    if not callback or not param then
        return
    end
    local fixInput = param.Input
    local function checkFunc(i)
        local v = fixInput[i]
        if v and (v.isChatInput or v.isNameInput) then
            local isNameCheck = v.isNameInput
            local isChatCheck = v.isChatInput
            if isNameCheck and IsForbidName(true) then
                return
            end
            if isChatCheck and IsForbidSay(true) then
                return
            end
            
            local SensitiveWordProxy = global.Facade:retrieveProxy(global.ProxyTable.SensitiveWordProxy)
            local function handle_Func(state, str, risk_param)
                if not str then
                    global.Facade:sendNotification(global.NoticeTable.SystemTips, GET_STRING(1006))
                    return
                end
        
                v.value = str
                if i == #fixInput then
                    param.Input      = (#fixInput > 0 and fixInput or nil)
                    callback(param)
                else
                    checkFunc(i + 1)
                end
            end
            if isNameCheck then
                SensitiveWordProxy:IsHaveSensitiveAddFilter(v.value, handle_Func)
            else
                SensitiveWordProxy:fixSensitiveTalkAddFilter(v.value, handle_Func, nil)
            end
        else
            if i == #fixInput then
                param.Input = (#fixInput > 0 and fixInput or nil)
                callback(param)
            else
                checkFunc(i + 1)
            end
        end
    end
    if fixInput and #fixInput > 0 then
        checkFunc(1)
    else
        callback(param)
    end
end

function SUILoader:load_render_Text(swidget, callback)
    local element           = swidget.element
    local text              = element.attr.text or ""
    local size              = tonumber(element.attr.size) or defaultFontSize
    local color             = element.attr.color or defaultColorID
    local link              = element.attr.link
    local width             = tonumber(element.attr.width)
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local scrollWidth       = tonumber(element.attr.scrollWidth)
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local auto              = tonumber(element.attr.auto)
    local platform          = tonumber(element.attr.platform)
    local clickInterval     = (tonumber(element.attr.clickInterval) or 0) * 0.001
    local tips              = element.attr.tips
    local tipsx             = tonumber(element.attr.tipsx) or 0
    local tipsy             = tonumber(element.attr.tipsy) or 0
    local tipWidth          = tonumber(element.attr.tipWidth) or 1136
    local simplenum         = tonumber(element.attr.simplenum) or 0
    local scrollWay         = tonumber(element.attr.scrollWay) or 0         -- 0 从右到左 1 从下到上
    local scrollTime        = tonumber(element.attr.scrollTime) or 4
    local scrollHeight      = tonumber(element.attr.scrollHeight)
    local thouFormat        = tonumber(element.attr.thouFormat) or 0
    local hexColor          = element.attr.hexcolor
    local bl                = math.floor(tonumber(element.attr.bl) or 0)


    text = string.gsub(text, "\\", "\r\n")
    text = string.trim(text)

    if tonumber(text) and bl >= 1 and bl <= 3 then
        local unitFunc = function(num, pointBit)
            pointBit = pointBit or 2
            if pointBit == 0 then
                return math.floor(num)
            end
            local iNum, fNum = math.modf(num)
            local fDecimal = math.pow(10, tostring(pointBit))
            local newFNum = math.floor(tostring(fNum * fDecimal))
            local newINum = iNum + (newFNum / fDecimal)
            return newINum
        end

        local blValue = 100
        if bl == 2 then
            blValue = 10000
        elseif bl == 3 then
            blValue = 1000
        end
        text = string.format("%s%%", unitFunc(text/blValue))
    end

    --
    local colorTable = {}
    if tonumber(color) then
        table.insert(colorTable, tonumber(color))
    else
        local slices = ssplit(color, ",")
        for _, v in ipairs(slices) do
            table.insert(colorTable, tonumber(v))
        end
    end

    --
    local useHex = false
    local hexColorTable = {}
    if hexColor then
        local slices = ssplit(hexColor, ",")
        for _, v in ipairs(slices) do
            if string.len(v) > 0 and string.find(v, "#") then
                table.insert(hexColorTable, v)
            end
        end
        if #hexColorTable > 0 then
            useHex = true
        end
    end

    local widget = global.SWidgetCache:generateRender("ccui.Text")
    widget:setScale(1)
    widget:setString(text)
    widget:setFontSize(size)
    widget:setFontName(defaultFontPath)
    widget:setTextColor(useHex and GetColorFromHexString(hexColorTable[1]) or GET_COLOR_BYID_C3B(colorTable[1]))
    widget:setTouchEnabled(false)
    widget:stopAllActions()
    widget:disableEffect(1)
    widget:disableEffect(6)
    widget:getVirtualRenderer():setMaxLineWidth(0)
    widget:enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)

    -- 加入元变量组件管理
    local isMateValue = false
    local metaValue = {}
    local content = text
    while content and string.len(content) > 0 do
        local find_info = {sfind(content, "$STM%((.-)%)")}
        local begin_pos = find_info[1]
        local end_pos   = find_info[2]

        if begin_pos and end_pos then
            isMateValue = true

            -- prefix
            if begin_pos ~= 1 then
                local substr = string.sub(content, 1, begin_pos - 1)
                table.insert(metaValue, substr)
            end

            -- metaValue
            local slices = ssplit(find_info[3], "_")
            table.insert(metaValue, {key = slices[1], param = slices[2]})

            -- suffix
            content = string.sub(content, end_pos+1, string.len(content))
        else
            table.insert(metaValue, content)
            content = ""
        end
    end
    if isMateValue then
        widget.useMetaValue = true
        global.Facade:sendNotification(global.NoticeTable.SUIMetaWidgetAdd, {metaValue = metaValue, widget = widget, lifewidget = widget, simplenum = simplenum, thouFormat = thouFormat})
    end
   
    -- width
    if width then
        local contentSize = widget:getContentSize()
        local renderer = widget:getVirtualRenderer()
        renderer:setMaxLineWidth(width)
    end

    -- link
    if link and string.len(link) > 0 or (tips and string.len(tips) > 0) then
        widget:setTouchEnabled(true)
        widget:addClickEventListener(function()
            DelayTouchEnabled(widget, clickInterval)

            widget:setScale(1 + 0.2)
            local function reback()
                widget:setScale(1)
            end
            performWithDelay(widget, reback, 0.03)
            
            if callback and link then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end

            if not global.isWinPlayMode then
                if tips and string.len(tips) > 0 then
                    local offset  = cc.p(tipsx, -tipsy)
                    local anchorPoint = cc.p(0.5, 1)
        
                    tips  = string.gsub(tips, "%^", "\\")
                    SHOW_SUI_DESCTIP( widget ,tips, tipWidth, offset, anchorPoint)
                end
            end

        end)

        -- 下划线
        widget:getVirtualRenderer():enableUnderline()
    end
   
    -- auto color
    local tbl = useHex and hexColorTable or colorTable
    if #tbl > 1 then
        local index = 1
        local function callback()
            index = index + 1
            if index > #tbl then
                index = 1
            end

            local color = useHex and GetColorFromHexString(tbl[index]) or GET_COLOR_BYID_C3B(tbl[index])
            widget:setTextColor(color)

            if link and string.len(link) > 0 then
                -- 下划线
                widget:getVirtualRenderer():disableEffect(6)
                widget:getVirtualRenderer():enableUnderline()
            end
        end
        schedule(widget, callback, 1)
    end

    self:addMouseOverTips(widget, element)

    -- auto scroll
    if scrollWidth then
        local widgetSize   = widget:getContentSize()
        local scrollH      = scrollHeight or widgetSize.height
        local scrollLayout = global.SWidgetCache:generateRender("ccui.Layout")
        scrollLayout:setClippingType(0)
        scrollLayout:setClippingEnabled(true)
        scrollLayout:setContentSize(cc.size(scrollWidth, scrollH))
        scrollLayout:addChild(widget)
        widget:setAnchorPoint(cc.p(0, 0))
        widget:setPosition(cc.p(0, 0))
        if scrollWay == 0 then
            widget:runAction(cc.RepeatForever:create(cc.Sequence:create(
                cc.MoveBy:create(scrollTime, cc.p(-widgetSize.width, 0)),
                cc.MoveBy:create(0, cc.p(widgetSize.width, 0)))
            ))
        elseif scrollWay == 1 then
            widget:setAnchorPoint(cc.p(0,1))
            widget:setPosition(cc.p(0, scrollH))
            widget:runAction(cc.RepeatForever:create(cc.Sequence:create(
                cc.MoveBy:create(scrollTime, cc.p(0, widgetSize.height)),
                cc.MoveBy:create(0, cc.p(0, -widgetSize.height))
            )))
        end
        return scrollLayout
    end

    -- auto event
    if widget:getChildByName("textAuto") then
        widget:removeChildByName("textAuto")
    end
    if platform == global.OperatingMode and auto and link and string.len(link) > 0 then
        local textAuto = ccui.Text:create()
        widget:addChild(textAuto)
        textAuto:setName("textAuto")
        textAuto:setString(string.format("(%s)", auto))
        textAuto:setFontSize(size)
        textAuto:setFontName(defaultFontPath)
        textAuto:setColor(cc.Color3B.WHITE)
        textAuto:setAnchorPoint(cc.p(0, 0.5))
        textAuto:setPosition(cc.p(widget:getContentSize().width + 3, widget:getContentSize().height/2))
        widget:disableEffect(6)

        local function autoCB()
            auto = auto - 1
            auto = math.max(auto, 0)
            textAuto:setString(string.format("(%s)", auto))  

            if auto == 0 then
                textAuto:stopAllActions()
                textAuto:removeFromParent()
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = link
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end
        end
        schedule(textAuto, autoCB, 1)
    end

    if simplenum == 1 then
        local text = widget:getString()
        if text and tonumber(text) then
            text = GetSimpleNumber(tonumber(text))
            widget:setString(text)
        end
    end

    if thouFormat == 1 then
        local text = widget:getString()
        if text and tonumber(text) then
            text = string.formatnumberthousands(tonumber(text))
            widget:setString(text)
        end
    end
   
    return widget
end

function SUILoader:load_render_TextAtlas(swidget, callback)
    local element           = swidget.element
    local img               = element.attr.img or "public/word_tywz_01.png"
    local iwidth            = tonumber(element.attr.iwidth) or 18
    local iheight           = tonumber(element.attr.iheight) or 28
    local schar             = element.attr.schar or "0"
    local text              = element.attr.text or ""

    local img               = SUIHelper.fixImageFileName(img)
    local fullPath          = (img and img ~= "") and string.format(getResFullPath("res/%s"), img) or ""
    if not fullPath or fullPath == "" or not global.FileUtilCtl:isFileExist(fullPath) then
        img                 = SUIHelper.fixImageFileName("public/word_tywz_01.png")
        fullPath            = string.format(getResFullPath("res/%s"), img)
    end

    local widget = ccui.TextAtlas:create()
    widget:setProperty( "", fullPath, iwidth, iheight, schar )
    widget:setScale(1)
   

    -- 加入元变量组件管理
    local isMateValue = false
    local metaValue = {}
    local content = text
    while content and string.len(content) > 0 do
        local find_info = {sfind(content, "$STM%((.-)%)")}
        local begin_pos = find_info[1]
        local end_pos   = find_info[2]

        if begin_pos and end_pos then
            isMateValue = true

            -- prefix
            if begin_pos ~= 1 then
                local substr = string.sub(content, 1, begin_pos - 1)
                table.insert(metaValue, substr)
            end

            -- metaValue
            local slices = ssplit(find_info[3], "_")
            table.insert(metaValue, {key = slices[1], param = slices[2]})

            -- suffix
            content = string.sub(content, end_pos+1, string.len(content))
        else
            table.insert(metaValue, content)
            content = ""
        end
    end
    if isMateValue then
        widget.useMetaValue = true
        global.Facade:sendNotification(global.NoticeTable.SUIMetaWidgetAdd, {metaValue = metaValue, widget = widget, lifewidget = widget})
    else
        widget:setString(text)
    end
   
   
    return widget
end

function SUILoader:load_render_RText(swidget, callback)
    local element           = swidget.element
    local text              = element.attr.text or ""
    local size              = tonumber(element.attr.size) or defaultFontSize
    local color             = tonumber(element.attr.color) or defaultColorID
    local width             = tonumber(element.attr.width) or 1136
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local scrollWidth       = tonumber(element.attr.scrollWidth)
    local scrollWay         = tonumber(element.attr.scrollWay) or 0         -- 0 从右到左 1 从下到上
    local scrollTime        = tonumber(element.attr.scrollTime) or 4
    local scrollHeight      = tonumber(element.attr.scrollHeight)


    local function textCB(str)
        if callback then
            local jsonData      = {}
            jsonData.Act        = str
            callback(jsonData)
        end
    end
    local ttfConfig = {
        outlineSize = outline,
        outlineColor = GET_COLOR_BYID_C3B(outlinecolor)
    }
    local SUI_RTEXT_FONT_PATH = SL:GetMetaValue("WINPLAYMODE") and SL:GetMetaValue("GAME_DATA","SUI_RTEXT_FONT_PATH") or nil
    local fontPath = SUI_RTEXT_FONT_PATH or defaultFontPath
    local widget = RichTextHelp:CreateRichTextWithFCOLOR(text, width, size, color, ttfConfig, textCB, SL:GetMetaValue("GAME_DATA","DEFAULT_VSPACE"), fontPath)

    self:addMouseOverTips(widget, element)

    -- auto scroll
    if scrollWidth then
        local widgetSize   = widget:getContentSize()
        local scrollH      = scrollHeight or widgetSize.height
        local scrollLayout = global.SWidgetCache:generateRender("ccui.Layout")
        scrollLayout:setClippingEnabled(true)
        scrollLayout:setClippingType(0)
        scrollLayout:setContentSize(cc.size(scrollWidth, scrollH))
        scrollLayout:addChild(widget)
        widget:setAnchorPoint(cc.p(0, 0))
        widget:setPosition(cc.p(0, 0))
        if scrollWay == 0 then
            widget:runAction(cc.RepeatForever:create(cc.Sequence:create(
                cc.MoveBy:create(scrollTime, cc.p(-widgetSize.width, 0)),
                cc.MoveBy:create(0, cc.p(widgetSize.width, 0)))
            ))
        elseif scrollWay == 1 then
            widget:setAnchorPoint(cc.p(0, 1))
            widget:setPosition(cc.p(0, scrollH))
            widget:runAction(cc.RepeatForever:create(cc.Sequence:create(
                cc.MoveBy:create(scrollTime, cc.p(0, widgetSize.height)),
                cc.MoveBy:create(0, cc.p(0, -widgetSize.height))
            )))
        end
        return scrollLayout
    end

    return widget
end

function SUILoader:load_render_Img(swidget, callback)
    local element           = swidget.element
    local bg                = tonumber(element.attr.bg)
    local img               = element.attr.img or ""
    local link              = element.attr.link
    local width             = tonumber(element.attr.width)
    local height            = tonumber(element.attr.height)
    local scale9l           = tonumber(element.attr.scale9l)
    local scale9r           = tonumber(element.attr.scale9r)
    local scale9t           = tonumber(element.attr.scale9t)
    local scale9b           = tonumber(element.attr.scale9b)
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local grey              = tonumber(element.attr.grey) or 0
    local flip              = tonumber(element.attr.flip) or 0
    local tips              = element.attr.tips
    local tipsx             = tonumber(element.attr.tipsx) or 0
    local tipsy             = tonumber(element.attr.tipsy) or 0
    local tipWidth          = tonumber(element.attr.tipWidth) or 1136
    local mainIndex         = element.attr._mainIndex

    local widget            = nil
    local img               = SUIHelper.fixImageFileName(img)
    local fullPath          = (img and img ~= "") and string.format(getResFullPath("res/%s"), img) or ""
    if not fullPath or fullPath == "" or not global.FileUtilCtl:isFileExist(fullPath) then
        widget              = global.SWidgetCache:generateEmptyImageRender("ccui.ImageView")
    else
        widget              = global.SWidgetCache:generateRender("ccui.ImageView")
    end

    widget:loadTexture(fullPath)
    widget:ignoreContentAdaptWithSize(false)
    widget:setContentSize(widget:getVirtualRendererSize())
    widget:setCapInsets(cc.rect(0, 0, 0, 0))
    widget:setScale9Enabled(false)
    widget:setTouchEnabled(false)
   
    if scale9l and scale9r and scale9t and scale9b then
        local contentSize   = widget:getContentSize()
        local x             = scale9l
        local y             = scale9t
        local width         = contentSize.width-scale9l-scale9r
        local height        = contentSize.height-scale9t-scale9b
        widget:setScale9Enabled(true)
        widget:setCapInsets({x = x, y = y, width = width, height = height})
    end

    -- link
    widget._linkClick = false
    if link and string.len(link) > 0 then
        widget:setTouchEnabled(true)
        widget:addClickEventListener(function()

            if mainIndex then
                -- 数据上报
                local NativeBridgeProxy = global.Facade:retrieveProxy(global.ProxyTable.NativeBridgeProxy)
                NativeBridgeProxy:GN_MainUIClickEvent({
                    index = mainIndex,
                    id = element.attr.id,
                    link = link
                })
            end

            if callback and link then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end

            if not global.isWinPlayMode then
                if tips and string.len(tips) > 0 then
                    local offset  = cc.p(tipsx, -tipsy)
                    local anchorPoint = cc.p(0.5, 1)
            
                    tips  = string.gsub(tips, "%^", "\\")
                    SHOW_SUI_DESCTIP( widget ,tips, tipWidth, offset, anchorPoint)
                end
            end
        end)
        if bg == 1 then
            widget._linkClick = true
        end
    end

    if bg == 1 then
        widget:setTouchEnabled(true)
        if global.isWinPlayMode then
            widget:setMouseEnabled(true)
            global.mouseEventController:registerMouseMoveEvent(widget)
        end
    end

    self:addMouseOverTips(widget, element)

    -- grey
    if grey == 1 then
        Shader_Grey(widget)
    else
        Shader_Normal(widget)
    end

    if flip == 1 then
        widget:setFlippedX(true)
    elseif flip == 2 then
        widget:setFlippedY(true)
    end


    return widget
end

function SUILoader:load_render_Button(swidget, callback, closeCB)
    local element           = swidget.element
    local nimg              = element.attr.nimg
    local pimg              = element.attr.pimg
    local mimg              = element.attr.mimg
    local text              = element.attr.text or ""
    local color             = tonumber(element.attr.color) or defaultColorID
    local size              = tonumber(element.attr.size) or defaultFontSize
    local width             = tonumber(element.attr.width)
    local height            = tonumber(element.attr.height)
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local tips              = element.attr.tips
    local tipsx             = tonumber(element.attr.tipsx) or 0
    local tipsy             = tonumber(element.attr.tipsy) or 0
    local textWidth         = tonumber(element.attr.textwidth)
    local grey              = tonumber(element.attr.grey) or 0
    local clickInterval     = (tonumber(element.attr.clickInterval) or 0) * 0.001
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local tipWidth          = tonumber(element.attr.tipWidth) or 1136
    local mainIndex         = element.attr._mainIndex

    text = string.gsub(text, "\\", "\r\n")
    text = string.trim(text)

    local nimg      = SUIHelper.fixImageFileName(nimg)
    local pimg      = SUIHelper.fixImageFileName(pimg)
    local mimg      = SUIHelper.fixImageFileName(mimg)
    local fullPathN = (nimg and string.len(nimg) > 0 and string.format(getResFullPath( "res/%s" ), nimg) or "")
    local fullPathP = (pimg and string.len(pimg) > 0 and string.format(getResFullPath( "res/%s" ), pimg) or "")
    local fullPathM = (mimg and string.len(mimg) > 0 and string.format(getResFullPath( "res/%s" ), mimg) or "")

    local widget    = nil
    local isNormalExist = fullPathN ~= "" and global.FileUtilCtl:isFileExist(fullPathN)
    local isPressExist = fullPathP ~= "" and global.FileUtilCtl:isFileExist(fullPathP)
    local isMouseExist = fullPathM ~= "" and global.FileUtilCtl:isFileExist(fullPathM)
    local Button_Type = 1
    --1-normalAndPress 2-Normal 3-Press 4-nil
    if isNormalExist and isPressExist  then
        Button_Type      = 1
    elseif  isNormalExist then
        Button_Type = 2
    elseif isPressExist then
        Button_Type = 3
    else
        Button_Type = 4
    end
    widget = global.SWidgetCache:generateButtonRender(Button_Type)
    widget:resetNormalRender()
    widget:resetPressedRender()
    widget:setTitleText(text)
    widget:setTitleColor(GET_COLOR_BYID_C3B(color))
    widget:setTitleFontName(defaultFontPath)
    widget:setTitleFontSize(size)
    widget:setTouchEnabled(false)
    widget:getTitleRenderer():setMaxLineWidth(0)
    widget:getTitleRenderer():enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)


    if isNormalExist then
        widget:loadTextureNormal(fullPathN)
    end
    if isPressExist then
        widget:loadTexturePressed(fullPathP)
    end

    --
    widget:ignoreContentAdaptWithSize(false)
    widget:setContentSize(widget:getVirtualRendererSize())
    local showTips      = tips and string.len(tips) > 0
    if isNormalExist and (isMouseExist or showTips) then
        if global.isWinPlayMode then
            local function checkResType(path)
                if global.SpriteFrameCache:getSpriteFrame(path) then
                    return 1
                end
                if global.FileUtilCtl:isFileExist(path) then
                    return 0
                end
                return 0
            end
            local function checkRes(path)
                local resType = checkResType(path)
                if isMouseExist and isNormalExist then
                    widget:loadTextureNormal(path, resType)
                end
            end

            local offset        = cc.p(tipsx, -tipsy)
            local anchor        = cc.p(0.5, 1)
            local function enterCB(touchPos)
                if global.userInputController:isTouching() or not widget:isVisible() then
                    return false
                end
                if not CheckNodeCanCallBack(widget, touchPos) then
                    return false
                end
                checkRes(fullPathM)
                if showTips then
                    tips        = string.gsub(tips, "%^", "\\")
                    showMouseOverTips(widget, tips, offset, anchor)
                end
            end
            local function leaveCB()
                checkRes(fullPathN)
                hideMouseOverTips()
            end
            -- widget:loadTextureMouseOver(fullPathN, fullPathM, enterCB, leaveCB)
            global.mouseEventController:registerMouseMoveEvent(
                widget,
                {
                    enter = enterCB,
                    leave = leaveCB,
                    checkIsVisible = true
                }
            )
        
        end
    end

    -- 加入元变量组件管理
    local isMateValue = false
    local metaValue = {}
    local content = text
    while content and string.len(content) > 0 do
        local find_info = {sfind(content, "$STM%((.-)%)")}
        local begin_pos = find_info[1]
        local end_pos   = find_info[2]

        if begin_pos and end_pos then
            isMateValue = true

            -- prefix
            if begin_pos ~= 1 then
                local substr = string.sub(content, 1, begin_pos - 1)
                table.insert(metaValue, substr)
            end

            -- metaValue
            local slices = ssplit(find_info[3], "_")
            table.insert(metaValue, {key = slices[1], param = slices[2]})

            -- suffix
            content = string.sub(content, end_pos+1, string.len(content))
        else
            table.insert(metaValue, content)
            content = ""
        end
    end
    if isMateValue then
        widget.useMetaValue = true
        global.Facade:sendNotification(global.NoticeTable.SUIMetaWidgetAdd, {metaValue = metaValue, widget = widget, lifewidget = widget})
    end

    if textWidth then
        local renderer = widget:getTitleRenderer()
        renderer:setMaxLineWidth(textWidth)
    end
   
    -- link
    if link and string.len(link) > 0 or (tips and string.len(tips) > 0) then
        widget:setTouchEnabled(true)
        widget:addClickEventListener(function()
            DelayTouchEnabled(widget, clickInterval)

            if mainIndex then
                -- 数据上报
                local NativeBridgeProxy = global.Facade:retrieveProxy(global.ProxyTable.NativeBridgeProxy)
                NativeBridgeProxy:GN_MainUIClickEvent({
                    index = mainIndex,
                    id = element.attr.id,
                    link = link
                })
            end

            if link == "@DEFAULT_CLOSE" then
                if closeCB then
                    closeCB()
                end

            elseif callback and link then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end

            if not global.isWinPlayMode then
                if tips and string.len(tips) > 0 then
                    local offset  = cc.p(tipsx, -tipsy)
                    local anchorPoint = cc.p(0.5, 1)
            
                    tips  = string.gsub(tips, "%^", "\\")
                    SHOW_SUI_DESCTIP( widget ,tips, tipWidth, offset, anchorPoint)
                end
            end

        end)
    end

    -- if nil == mimg then
    --     self:addMouseOverTips(widget, element)
    -- end

    -- grey
    if grey == 1 then
        Shader_Grey(widget)
    else
        Shader_Normal(widget)
    end

    return widget
end

function SUILoader:load_render_CheckBox(swidget, callback)
    local element           = swidget.element
    local checkboxid        = element.attr.checkboxid
    local nimg              = element.attr.nimg
    local pimg              = element.attr.pimg
    local default           = tonumber(element.attr.default) or 0
    local submit            = tonumber(element.attr.submit) or 0
    local delay             = math.max(tonumber(element.attr.delay) or 0, 1/60)
    local count             = tonumber(element.attr.count) or 0
    local link              = element.attr.link


    local nimg = SUIHelper.fixImageFileName(nimg)
    local pimg = SUIHelper.fixImageFileName(pimg)
    local widget = ccui.CheckBox:create()
    widget:loadTextureBackGround(string.format(getResFullPath("res/%s"), nimg))
    widget:loadTextureFrontCross(string.format(getResFullPath("res/%s"), pimg))
    widget:setSelected(default == 1)
    widget:setTouchEnabled(true)
    widget:ignoreContentAdaptWithSize(false)
    widget:stopAllActions()

    -- link
    if link and string.len(link) > 0 then
        widget:addEventListener(function()
            local counting = 0
            local function delayCB()
                if callback then
                    local checkBoxTable = self:getCheckBoxTableByID(checkboxid)
                    local jsonData      = {}
                    jsonData.Act        = link
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    callback(jsonData)
                end

                counting = counting + 1
                if count ~= -1 and counting >= count then
                    widget:stopAllActions()
                end
            end
            widget:stopAllActions()
            schedule(widget, delayCB, delay)
        end)
    end
   
    if checkboxid and self._checkboxWidgets then
        self._checkboxWidgets[checkboxid] = widget
    end

    return widget
end

function SUILoader:load_render_ListView(swidget, callback)
    local element           = swidget.element
    local width             = element.attr.width or 200
    local height            = element.attr.height or 200
    local color             = tonumber(element.attr.color)
    local direction         = tonumber(element.attr.direction) or 1
    local bounce            = tonumber(element.attr.bounce) or 1
    local margin            = tonumber(element.attr.margin) or 0
    local default           = tonumber(element.attr.default)
    local cantouch          = tonumber(element.attr.cantouch) or 1

    local widget = global.SWidgetCache:generateRender("ccui.ListView")
    widget:ignoreContentAdaptWithSize(false)
    widget:setClippingEnabled(true)
    widget:setClippingType(0)
    widget:setTouchEnabled(true)
    widget:setDirection(direction)
    widget:setGravity(0)
    widget:setItemsMargin(margin)
    widget:setBounceEnabled(bounce == 1)
    widget:setBackGroundColorType(0)
    widget:stopAllActions()

    if DEBUG_MODE then
        widget:setBackGroundColorType(1)
        widget:setBackGroundColorOpacity(100)
        widget:setBackGroundColor(cc.Color3B.GREEN)
    end

    -- color
    if color then
        widget:setBackGroundColorType(1)
        widget:setBackGroundColorOpacity(255)
        widget:setBackGroundColor(GET_COLOR_BYID_C3B(color))
    end

    -- default
    if default then
        -- default
        local function callback()
            default = default - 1
            local index = math.max(default, 0)
            widget:jumpToItem(index, cc.p(0, 0), cc.p(0, 0))
            widget:doLayout()
        end
        performWithDelay(widget, callback, 1/60)
    end

    if cantouch == 0 then
        widget:setTouchEnabled(false)
    else
        widget._unRefPos = true
    end
   
    return widget
end

function SUILoader:load_render_Effect(swidget, callback)
    local element           = swidget.element
    local effecttype        = tonumber(element.attr.effecttype) or 0
    local effectid          = tonumber(element.attr.effectid) or 9999
    local sex               = tonumber(element.attr.sex) or 0
    local act               = tonumber(element.attr.act) or 0
    local dir               = tonumber(element.attr.dir) or 5
    local speed             = tonumber(element.attr.speed) or 1
    local scale             = tonumber(element.attr.scale) or 1
    local count             = tonumber(element.attr.count) or 0
    local grey              = tonumber(element.attr.grey) or 0
    local link              = element.attr.link
    local scalex            = tonumber(element.attr.scalex)
    local scaley            = tonumber(element.attr.scaley)

    -- 0.普通特效 1.npc模型 2.怪物模型 3.技能特效 4.人物 5.武器 6.翅膀 7.发型 8.盾牌
    local widget        = nil
    if effecttype == 0 then
        -- 特效
        widget = global.FrameAnimManager:CreateSFXAnim(effectid)
        widget:Play(0, 0, true, speed)
        
    elseif effecttype == 1 then
        -- NPC
        widget = global.FrameAnimManager:CreateActorNpcAnim(effectid)
        widget:Play(act, dir, true, speed)

    elseif effecttype == 2 then
        -- 怪物
        widget = global.FrameAnimManager:CreateActorMonsterAnim(effectid, act)
        widget:Play(act, dir, true, speed)

    elseif effecttype == 3 then
        -- 技能
        widget = global.FrameAnimManager:CreateSkillEffAnim(effectid, dir)
        widget:Play(act, dir, true, speed)

    elseif effecttype == 4 then
        -- 人物
        widget = global.FrameAnimManager:CreateActorPlayerAnim(effectid, sex, act)
        widget:Play(act, dir, true, speed)

    elseif effecttype == 5 then
        -- 武器
        widget = global.FrameAnimManager:CreateActorPlayerWeaponAnim(effectid, sex, act)
        widget:Play(act, dir, true, speed)

    elseif effecttype == 6 then
        -- 翅膀
        widget = global.FrameAnimManager:CreateActorPlayerWingsAnim(effectid, sex, act)
        widget:Play(act, dir, true, speed)

    elseif effecttype == 7 then
        -- 发型
        widget = global.FrameAnimManager:CreateActorPlayerHairAnim(effectid, sex, act)
        widget:Play(act, dir, true, speed)
   
    elseif effecttype == 8 then
        -- 盾牌
        widget = global.FrameAnimManager:CreateActorPlayerShieldAnim(effectid, sex, act)
        widget:Play(act, dir, true, speed)

    else
        widget = global.FrameAnimManager:CreateSFXAnim(1)
        widget:Play(0, 0, true, speed)
    end

    if widget then
        widget:setScale(scale)
        if not tonumber(element.attr.scale) and scalex then
            widget:setScaleX(scalex)
        end
        if not tonumber(element.attr.scale) and scaley then
            widget:setScaleY(scaley)
        end
        
        
        -- 播放次数
        local counting = 0
        widget:SetAnimEventCallback(
            function(_, eventType)
                counting = counting + 1
               
                if counting == count then
                    if link then
                        if callback then
                            local jsonData      = {}
                            jsonData.Act        = link
                            callback(jsonData)
                        end
                    end

                    widget:Stop()
                    widget:setVisible(false)
                end
            end
        )

        -- 灰化处理
        if grey == 1 then
            Shader_Grey(widget)
        else
            Shader_Normal(widget)
        end
    end

    return widget
end

function SUILoader:load_render_Frames(swidget, callback)
    local element           = swidget.element
    local prefix            = element.attr.prefix
    local suffix            = element.attr.suffix
    local speed             = tonumber(element.attr.speed) or 100
    local count             = tonumber(element.attr.count) or 1
    local loop              = tonumber(element.attr.loop) or -1
    local finishframe       = tonumber(element.attr.finishframe)
    local finishhide        = tonumber(element.attr.finishhide)
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox

    local img       = SUIHelper.fixImageFileName(prefix .. "1" .. suffix)
    local fullPath  = string.format(getResFullPath("res/%s"), img)
    local widget    = nil
    if global.FileUtilCtl:isFileExist(fullPath) then
        widget      = global.SWidgetCache:generateRender("ccui.ImageView")
    else
        widget      = ccui.ImageView:create()
    end
    widget:loadTexture(fullPath)
    widget:ignoreContentAdaptWithSize(false)
    widget:setContentSize(widget:getVirtualRendererSize())
    widget:setTouchEnabled(false)
    widget:setCapInsets(cc.rect(0, 0, 0, 0))
    widget:setScale9Enabled(false)
    widget:stopAllActions()

    local function finishCB()
        if finishframe then
            fullPath = string.format(getResFullPath("res/%s"), SUIHelper.fixImageFileName(prefix .. finishframe .. suffix))
            widget:loadTexture(fullPath)
        end
        if finishhide == 1 then
            widget:setVisible(false)
        end
    end

    local index     = 1
    local counting  = 0
    local function delayCB()
        fullPath    = string.format(getResFullPath("res/%s"), SUIHelper.fixImageFileName(prefix .. index .. suffix))
        widget:loadTexture(fullPath)
        
        index       = index + 1
        if index > count then
            index = 1

            counting = counting + 1
            if loop ~= -1 and counting >= loop then
                widget:stopAllActions()
                finishCB()
            end
        end
    end
    schedule(widget, delayCB, speed*0.01)
    delayCB()

    -- link
    if link and string.len(link) > 0 then
        widget:setTouchEnabled(true)
        widget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end

    return widget
end

function SUILoader:load_render_Input(swidget, callback)
    local element           = swidget.element
    local inputid           = element.attr.inputid
    local inputtype         = tonumber(element.attr.type) or 0
    local text              = element.attr.text or ""
    local place             = element.attr.place
    local placecolor        = element.attr.placecolor or defaultColorID
    local width             = element.attr.width
    local height            = element.attr.height
    local color             = element.attr.color or defaultColorID
    local size              = tonumber(element.attr.size) or defaultFontSize
    local mincount          = element.attr.mincount
    local maxcount          = tonumber(element.attr.maxcount) or 10000
    local errortips         = element.attr.errortips
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local linkType          = tonumber(element.attr.linkType) or 1
    local link              = element.attr.link
    local onlyCh            = tonumber(element.attr.onlyCh) and tonumber(element.attr.onlyCh) == 1
    local isChatInput       = (tonumber(element.attr.isChatInput) or 1) == 1
    local isNameInput       = tonumber(element.attr.isNameInput) == 1

    local fontPath = defaultFontPath
    local widget = ccui.EditBox:create({width=width, height=height}, global.MMO.PATH_RES_ALPHA)
    widget:setFontColor(GET_COLOR_BYID_C3B(tonumber(color)))
    widget:setColor(GET_COLOR_BYID_C3B(tonumber(color)))
    if global.isMobile then
        widget:setFontName(fontPath)
    end
    widget:setFontSize(size)
    widget:setString(text)
    widget:setPlaceHolder(place)
    widget:setPlaceholderFontColor(GET_COLOR_BYID_C3B(tonumber(placecolor)))
    widget:setPlaceholderFontSize(size)
    widget:setTextHorizontalAlignment(0)
    widget:setMaxLength(maxcount)

    -- native offset
    if global.Platform == cc.PLATFORM_OS_WINDOWS then
    elseif global.Platform == cc.PLATFORM_OS_ANDROID then
        widget:setNativeOffset( cc.p( 0, -15 ) )
    else
    end

    -- 输入类型
    if inputtype == 1 or inputtype == 3 then
        widget:setInputMode(2)
    elseif inputtype == 2 then
        widget:setInputFlag(0)
    end

    if inputid and self._inputWidgets then
        self._inputWidgets[inputid] = {widget = widget, inputFlag = (inputtype ~= 1 and "INPUTTEXT" or ""), isChatInput = isChatInput, isNameInput = isNameInput}
    end

    local function eventCB(sender, eventType)
        if eventType == 2 and onlyCh then
            local str = sender:getString()
            sender:setString(CheckInputOnlyChinese(str))
        end
        if eventType == 2 and (inputtype == 1 or inputtype == 3) then
            local str = sender:getString()
            if string.find(str,"[^%d]+") then
                local s, d = string.find(str,"[^%d]+")
                local str1 = string.sub(str, 1, s-1)
                local str2 = string.sub(str, d+1)
                sender:setString(str1..str2)
            end
            if inputtype == 3 then
                local str = sender:getString()
                local num = tonumber(str)
                if num and tostring(num) ~= str then
                    sender:setString(num)
                end
            end
        end
    end

    if link then
        widget:addEventListener(function(sender, eventType)
            eventCB(sender, eventType)
            if linkType == eventType then
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = link
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end
        end)
    else
        widget:addEventListener(eventCB)
    end
   
    return widget
end

function SUILoader:load_render_COUNTDOWN(swidget, callback)
    local element           = swidget.element
    local time              = tonumber(element.attr.time) or 10
    local count             = tonumber(element.attr.count) or 1
    local color             = tonumber(element.attr.color) or defaultColorID
    local size              = tonumber(element.attr.size) or defaultFontSize
    local showWay           = tonumber(element.attr.showWay) or 0
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local link              = element.attr.link


    local widget = global.SWidgetCache:generateRender("ccui.Text")
    if showWay == 1 then
        widget:setString(TimeFormatToString(time))
    else
        widget:setString(string.format(GET_STRING(2006), time))
    end
    widget:setFontSize(size)
    widget:setFontName(defaultFontPath)
    widget:setTextColor(GET_COLOR_BYID_C3B(color))
    widget:enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)
    widget:setTouchEnabled(false)
    widget:stopAllActions()

    local counting = 0
    local remaining = time
    local function scheduleCallback()
        if showWay == 1 then
            widget:setString(TimeFormatToString(remaining))
        else
            widget:setString(string.format(GET_STRING(2006), remaining))
        end
        remaining = remaining - 1
        if remaining < 0 then
            -- link
            if link and string.len(link) > 0 then
                if callback then
                    local jsonData = {}
                    jsonData.Act   = link
                    callback(jsonData)
                end
            end

            remaining = time
            counting  = counting + 1
            if count > 0 and counting >= count then
                widget:stopAllActions()
            end
        end
    end
    schedule(widget, scheduleCallback, 1)
    scheduleCallback()

    return widget
end

function SUILoader:load_render_ItemShow(swidget, callback)
    local element           = swidget.element
    local itemid            = tonumber(element.attr.itemid) or 1
    local itemcount         = tonumber(element.attr.itemcount) or 1
    local showtips          = tonumber(element.attr.showtips) or 1
    local bgtype            = tonumber(element.attr.bgtype)
    local scale             = tonumber(element.attr.scale) or 1
    local grey              = tonumber(element.attr.grey) or 0
    local lock              = tonumber(element.attr.lock) or 0
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local countColor        = tonumber(element.attr.color) or defaultColorID
    local dblink            = element.attr.dblink
    local effectshow        = tonumber(element.attr.effectshow) or 1
    local itemDataStr       = element.attr.itemdata
    local itemName          = element.attr.itemname
    local itemData          = nil

    if itemDataStr and string.len(tostring(itemDataStr)) > 0 then
        local json = cjson.decode(itemDataStr)
        if json and next(json) then
            itemData = ChangeItemServersSendDatas(json)
        end
    end

    if itemName and string.len(itemName) > 0 then
        local ItemConfigProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemConfigProxy)
        local index = ItemConfigProxy:GetItemIndexByName(itemName)
        if index and not tonumber(element.attr.itemid) then
            itemid = index
        end
    end

    local contentSize       = cc.size(66,66)
   
    local widget            = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    local info              = {}
    info.index              = itemid
    info.look               = showtips == 1
    info.count              = itemcount
    info.bgVisible          = bgtype == 1
    info.color              = countColor
    info.itemData           = itemData
    if not info.look and global.isWinPlayMode then
        info.noMouseTips = true
    end
    if effectshow == 2 then
        info.showModelEffect = true
    elseif effectshow == 0 then
        info.isShowEff = false
    end
    local goodsItem         = GoodsItem:create(info)
    widget:addChild(goodsItem)
    goodsItem:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
    goodsItem:setScale(scale)
    goodsItem:setIconGrey(grey == 1)

    if dblink and string.len(dblink) > 0 then
        if not (showtips == 1) then
            goodsItem:addLookItemInfoEvent(nil, 2)
        end
        goodsItem:addDoubleEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = dblink
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end

    if lock == 1 then
        local imageLock     = ccui.ImageView:create()
        imageLock:setAnchorPoint(cc.p(0, 1))
        goodsItem:addChild(imageLock)
        if global.isWinPlayMode then
            imageLock:setScale(0.7)
        end
        imageLock:loadTexture(global.MMO.PATH_RES_PUBLIC .. "lock.png")
        imageLock:setPosition(cc.p(0, goodsItem:getContentSize().height))
    end

    if link and not dblink then
        local linkWidget    = global.SWidgetCache:generateRender("ccui.Widget")
        widget:addChild(linkWidget)
        linkWidget:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        linkWidget:setContentSize(contentSize)
        linkWidget:setTouchEnabled(true)
        linkWidget:setSwallowTouches(false)
        linkWidget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end

   
    return widget
end

function SUILoader:load_render_DBItemShow(swidget, callback)
    local element           = swidget.element
    local makeindex         = tonumber(element.attr.makeindex)  or 1
    local showtips          = tonumber(element.attr.showtips) or 1
    local bgtype            = tonumber(element.attr.bgtype)
    local scale             = tonumber(element.attr.scale) or 1
    local grey              = tonumber(element.attr.grey) or 0
    local showstar          = tonumber(element.attr.showstar) == 1
    local count             = tonumber(element.attr.count)
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local dblink            = element.attr.dblink
    local effectshow        = tonumber(element.attr.effectshow) or 1 -- 1只显示背包 2只显示内观 0不显示

    local itemData          = nil
    if not itemData then
        local EquipProxy    = global.Facade:retrieveProxy(global.ProxyTable.Equip)
        itemData            = EquipProxy:GetEquipDataByMakeIndex(makeindex)
    end
    if not itemData then
        local BagProxy      = global.Facade:retrieveProxy(global.ProxyTable.Bag)
        itemData            = BagProxy:GetItemDataByMakeIndex(makeindex)
    end

    if not itemData then
        local QuickUseProxy = global.Facade:retrieveProxy(global.ProxyTable.QuickUseProxy)
        itemData            = QuickUseProxy:GetQucikUseDataByMakeIndex(makeindex)
    end

    if not itemData then
        local LookPlayerProxy = global.Facade:retrieveProxy(global.ProxyTable.LookPlayerProxy)
        itemData = LookPlayerProxy:GetLookPlayerItemDataByMakeIndex(makeindex)
    end


    local contentSize       = cc.size(66,66)
    local widget            = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    if itemData then
        local info          = {}
        info.index          = itemData.Index
        info.itemData       = itemData
        info.look           = showtips == 1
        info.bgVisible      = bgtype == 1
        info.starLv         = showstar
        if not info.look and global.isWinPlayMode then
            info.noMouseTips = true
        end
        if effectshow == 2 then
            info.showModelEffect = true
        elseif effectshow == 0 then
            info.isShowEff = false
        end
        local goodsItem     = GoodsItem:create(info)
        widget:addChild(goodsItem)
        goodsItem:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        goodsItem:setScale(scale)
        goodsItem:setIconGrey(grey == 1)
        if count then
            goodsItem:setCount(count)
        end
        if dblink and string.len(dblink) then
            if not (showtips == 1) then
                goodsItem:addLookItemInfoEvent(nil, 2)
            end
            goodsItem:addDoubleEventListener(function()
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = dblink
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end)
        end
    end

    if link and string.len(link) > 0 and not dblink then
        local linkWidget    = global.SWidgetCache:generateRender("ccui.Widget")
        widget:addChild(linkWidget)
        linkWidget:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        linkWidget:setContentSize(contentSize)
        linkWidget:setTouchEnabled(true)
        linkWidget:setSwallowTouches(false)
        linkWidget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end
   
    return widget
end

function SUILoader:load_render_CostItem(swidget, callback)
    local element           = swidget.element
    local itemid            = tonumber(element.attr.itemid) or 1
    local itemcount         = tonumber(element.attr.itemcount) or 1
    local itemScale         = tonumber(element.attr.itemscale)
    local fontSize          = tonumber(element.attr.fontsize)
    local titleText         = element.attr.title
    local simplenum         = tonumber(element.attr.simplenum) or 0

    local CostItemCell      = requireLayerUI("extra_layer/CostItemCell")
    local widget            = CostItemCell:create(string.format("%s#%s", itemid, itemcount), {itemScale = itemScale, titleText = titleText, fontSize = fontSize, simplenum = simplenum})

    return widget
end

function SUILoader:load_render_Layout(swidget, callback)
    local element           = swidget.element
    local width             = tonumber(element.attr.width) or 1
    local height            = tonumber(element.attr.height) or 1
    local color             = tonumber(element.attr.color)
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local clipEnable        = (tonumber(element.attr.clip) or 0) == 1

    local widget = global.SWidgetCache:generateRender("ccui.Layout")
    widget:setContentSize(cc.size(width, height))
    widget:setBackGroundColorType(0)
    widget:setTouchEnabled(false)

    if DEBUG_MODE then
        widget:setBackGroundColorType(1)
        widget:setBackGroundColorOpacity(100)
        widget:setBackGroundColor(cc.Color3B.BLUE)
    end

    -- color
    if color then
        widget:setBackGroundColorType(1)
        widget:setBackGroundColorOpacity(255)
        widget:setBackGroundColor(GET_COLOR_BYID_C3B(color))
    end

    -- clip
    if clipEnable then
        widget:setClippingEnabled(true)
        widget:setClippingType(0)
    end

    -- link
    if link and string.len(link) > 0 then
        widget:setTouchEnabled(true)
        widget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end

    return widget
end

function SUILoader:load_render_ITEMBOX(swidget, callback)
    local element           = swidget.element
    local width             = tonumber(element.attr.width) or 1
    local height            = tonumber(element.attr.height) or 1
    local boxindex          = tonumber(element.attr.boxindex)
    local img               = element.attr.img
    local stdmode           = element.attr.stdmode


    local img       = SUIHelper.fixImageFileName(img)
    local fullPath  = string.format(getResFullPath("res/%s"), img)
   
    local widget    = nil
    if img and img ~= "" and global.FileUtilCtl:isFileExist(fullPath) then
        widget      = global.SWidgetCache:generateRender("ccui.ImageView")
    else
        widget      = ccui.ImageView:create()
    end

    widget:loadTexture(fullPath)
    widget:ignoreContentAdaptWithSize(false)
    widget:setContentSize(widget:getVirtualRendererSize())
    widget:setCapInsets(cc.rect(0, 0, 0, 0))
    widget:setScale9Enabled(false)
    widget:setTouchEnabled(true)

    --
    local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
    local function addItemToITEMBOX(touchPos)
        local state = ItemMoveProxy:GetMovingItemState()
        if state then
            local goToName      = ItemMoveProxy.ItemGoTo.ITEMBOX
            local data          = {}
            data.target         = goToName
            data.stdmode        = stdmode
            data.widget         = widget
            data.boxindex       = boxindex
            ItemMoveProxy:CheckAndCallBack( data )
        else
            return -1
        end
    end
    local function setNoswallowMouse()
        return -1
    end
    global.mouseEventController:registerMouseButtonEvent(
        widget,
        {
            down_r    = setNoswallowMouse,
            special_r = addItemToITEMBOX
        }
    )

   
    --
    self:addMouseOverTips(widget, element)

    -- 加入管理
    global.Facade:sendNotification(global.NoticeTable.SUIITEMBOXWidgetAdd, {boxindex = boxindex, widget = widget})

    return widget
end

function SUILoader:load_render_EquipShow(swidget, callback)
    local element           = swidget.element
    local index             = tonumber(element.attr.index) or 0
    local showtips          = tonumber(element.attr.showtips) or 1
    local bgtype            = tonumber(element.attr.bgtype)
    local scale             = tonumber(element.attr.scale) or 1
    local grey              = tonumber(element.attr.grey) or 0
    local showstar          = tonumber(element.attr.showstar) == 1
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local dblink            = element.attr.dblink
    local effectshow        = tonumber(element.attr.effectshow) or 1 -- 1只显示背包 2只显示内观 0不显示

    local contentSize       = cc.size(66,66)
   
    local widget            = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)


    local EquipProxy        = global.Facade:retrieveProxy(global.ProxyTable.Equip)
    local equipData         = EquipProxy:GetEquipDataByPos(index)
    if equipData then
        local info          = {}
        info.index          = equipData.Index
        info.itemData       = equipData
        info.look           = showtips == 1
        info.bgVisible      = bgtype == 1
        info.starLv         = showstar
        if not info.look and global.isWinPlayMode then
            info.noMouseTips = true
        end
        if effectshow == 2 then
            info.showModelEffect = true
        elseif effectshow == 0 then
            info.isShowEff = false
        end
        local goodsItem     = GoodsItem:create(info)
        widget:addChild(goodsItem)
        goodsItem:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        goodsItem:setScale(scale)
        goodsItem:setIconGrey(grey == 1)

        if dblink and string.len(dblink) then
            if not (showtips == 1) then
                goodsItem:addLookItemInfoEvent(nil, 2)
            end
            goodsItem:addDoubleEventListener(function()
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = dblink
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end)
        end
    end

    if link and not dblink then
        local linkWidget    = global.SWidgetCache:generateRender("ccui.Widget")
        widget:addChild(linkWidget)
        linkWidget:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        linkWidget:setContentSize(contentSize)
        linkWidget:setTouchEnabled(true)
        linkWidget:setSwallowTouches(false)
        linkWidget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end

   
    return widget
end

function SUILoader:load_render_BAGITEMS(swidget, callback)
    local element               = swidget.element
    local condition             = element.attr.condition or ""
    local exclude               = element.attr.exclude or ""
    local select                = element.attr.select or ""
    local count                 = tonumber(element.attr.count) or 12
    local row                   = tonumber(element.attr.row) or 2
    local selecttype            = tonumber(element.attr.selecttype) or 0
    local showstar              = tonumber(element.attr.showstar) == 1
    local iwidth                = tonumber(element.attr.iwidth) or 70
    local iheight               = tonumber(element.attr.iheight) or 70
    local iimg                  = element.attr.iimg
    local filter1               = element.attr.fliter1 or element.attr.filter1 or ""
    local filter2               = element.attr.fliter2 or element.attr.filter2 or ""
    local filter3               = element.attr.fliter3 or element.attr.filter3 or ""
    local link                  = element.attr.link
    local conditionEx           = element.attr.conditionEx
    local conditionParam        = element.attr.conditionParam
    local conditionOnOff        = tonumber(element.attr.conditionOnOff) or 0
    local condition2            = element.attr.condition2
    local dblink                = element.attr.dblink
    local effectshow            = tonumber(element.attr.effectshow) or 1
    local exBind                = tonumber(element.attr.exbind) == 1
    local showtips              = (tonumber(element.attr.showtips) or 0) == 1
    local includeQuick          = (tonumber(element.attr.includequick) or 0) == 1
    local clickInterval         = (tonumber(element.attr.clickInterval) or 0) * 0.001

    local itemscaleX            = iwidth / 70
    local itemscaleY            = iheight / 70

    -- 是否满足显示条件
    local conditionT            = {}
    local slices1               = ssplit(condition, ",")
    local slices2               = {}
    for _, v in pairs(slices1) do
        slices2                 = ssplit(v, "#")
        tinsert(conditionT, {StdMode = tonumber(slices2[1]), Shape = tonumber(slices2[2])})
    end
    -- 唯一ID过滤
    local excludeT              = {}
    local slices                = ssplit(exclude, ",")
    for _, v in pairs(slices) do
        tinsert(excludeT, tonumber(v))
    end
   
    -- 道具ID过滤,存在不显示
    local filter1T              = {}
    local slices                = ssplit(filter1, ",")
    for _, v in pairs(slices) do
        tinsert(filter1T, tonumber(v))
    end
   
    -- 道具名过滤,存在不显示
    local filter2T              = {}
    local slices                = ssplit(filter2, ",")
    for _, v in pairs(slices) do
        if v ~= "" then
            tinsert(filter2T, v)
        end
    end

    -- 道具ID过滤,存在才显示
    local filter3T              = {}
    local slices                = ssplit(filter3, ",")
    for _, v in pairs(slices) do
        if v ~= "" then
            tinsert(filter3T, v)
        end
    end

    local function conditionAble(item)
        if conditionEx and tonumber(conditionEx) == 1 then
            local starLv = item.Star or 0
            if conditionOnOff and conditionOnOff == 0 then
                if conditionParam and starLv < tonumber(conditionParam) then
                    return false
                end
            elseif conditionOnOff == 1 then
                if conditionParam and starLv > tonumber(conditionParam) then
                    return false
                end
            end
        end
        -- 被排除
        for _, v in ipairs(excludeT) do
            if v == item.MakeIndex then
                return false
            end
        end

        -- 道具ID过滤
        for _, v in ipairs(filter1T) do
            if v == item.Index then
                return false
            end
        end

        -- 道具名过滤
        for _, v in ipairs(filter2T) do
            if v == item.Name then
                return false
            end
        end

        -- 绑定过滤
        if exBind and CheckItemisBind(item) then
            return false
        end

        -- 道具ID/道具名过滤
        if #filter3T > 0 then
            for _, v in ipairs(filter3T) do
                if tonumber(v) == item.Index or v == item.Name then
                    return true
                end
            end
            return false
        end
      
        -- 筛选
        if condition == "*" then
            return true
        end
        for _, v in pairs(conditionT) do
            if v.StdMode == item.StdMode and (not v.Shape or v.Shape == item.Shape) then
                return true
            end
        end

        if condition2 then
            if tonumber(item.sDivParam2) and tonumber(item.sDivParam2) == tonumber(condition2) then
                return true
            elseif string.find(tostring(condition2), "#") then
                local paramList = string.split(tostring(condition2), "#")
                for _, param in ipairs(paramList) do
                    if tonumber(param) == tonumber(item.sDivParam2) then
                        return true
                    end
                end
            end
        end
        return false
    end

    -- 是否选中
    local selects               = {}
    local slices                = ssplit(select, ",")
    for _, v in pairs(slices) do
        tinsert(selects, tonumber(v))
    end
    local function selectAble(item)
        for _, v in pairs(selects) do
            if v == item.MakeIndex then
                return true
            end
        end
        return false
    end


    local itemWid               = iwidth
    local itemHei               = iheight
    local col                   = math.ceil(count / row)
    local contentSize           = cc.size(col * itemWid, row * itemHei)

    local widget                = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    --
    local boxes = {}
    for i = 1, count do
        local x                 = ((i - 1) % col + 0.5) * itemWid
        local y                 = contentSize.height - (mfloor((i - 1) / col) + 0.5) * itemHei
        local iimg              = (iimg and iimg ~= "") and SUIHelper.fixImageFileName(iimg) or "public/1900000664.png"
        local fullPath          = string.format(getResFullPath("res/%s"), iimg)
        local imageBG           = ccui.ImageView:create()
        widget:addChild(imageBG)
        imageBG:loadTexture(fullPath)
        GUI:Image_setScale9Slice(imageBG, 21, 22, 21, 22)
            GUI:setContentSize(imageBG, itemWid, itemHei)        
        imageBG:setTouchEnabled(false)
        imageBG:setAnchorPoint(cc.p(0.5, 0.5))
        imageBG:setPosition(cc.p(x, y))
        tinsert(boxes, imageBG)
    end

    -- bag items
    local BagProxy              = global.Facade:retrieveProxy(global.ProxyTable.Bag)
    local items                 = {}
    local BagMaxNum = BagProxy:GetMaxBag()
    for i = 1, BagMaxNum do
        local itemMakeIndex     = BagProxy:GetMakeIndexByBagPos(i)
        if itemMakeIndex then
            local itemData      = BagProxy:GetItemDataByMakeIndex(itemMakeIndex)
            if itemData and conditionAble(itemData) then
                tinsert(items, itemData)
            end
        end
    end

    if includeQuick then
        local QuickUseProxy = global.Facade:retrieveProxy(global.ProxyTable.QuickUseProxy)
        local quickUseData = QuickUseProxy:GetQuickUseData()
        for _, itemData in pairs(quickUseData) do
            if itemData and conditionAble(itemData) then
                tinsert(items, itemData)
            end
        end
    end
    --

    -- show
    for index, item in ipairs(items) do
        local imageBG           = boxes[index]
        if imageBG then
            local size          = imageBG:getContentSize()

            -- 道具图标
            local info = {index = item.Index, itemData = item, starLv = showstar}
            if effectshow == 2 then
                info.showModelEffect = true
            elseif effectshow == 0 then
                info.isShowEff = false
            end
            info.look           = showtips
            if not info.look and global.isWinPlayMode then
                info.noMouseTips = true
            end
            local goodsItem     = GoodsItem:create(info)
            imageBG:addChild(goodsItem)
            goodsItem:setPosition(cc.p(size.width/2, size.height/2))
            goodsItem._canLooks = true
            goodsItem:addLookItemInfoEvent(nil, 1)
            goodsItem:setScaleX(itemscaleX)
            goodsItem:setScaleY(itemscaleY)
            
            -- link
            if link and string.len(link) > 0 then
                goodsItem:addTouchEventListener(function()
                    if clickInterval > 0 then
                        goodsItem:DelayTouchEnabled(clickInterval)
                    end
                    local selected          = clone(selects)
                    if selecttype == 0 then
                        -- 多选
                        if selectAble(item) then
                            for key, value in pairs(selected) do
                                if item.MakeIndex == value then
                                    table.remove(selected, key)
                                    break
                                end
                            end
                        else
                            tinsert(selected, item.MakeIndex)
                        end
                    else
                        -- 单选
                        if selectAble(item) then
                            selected = {}
                        else
                            selected = {item.MakeIndex}
                        end
                    end

                    local jsonData          = {}
                    jsonData.Act            = link
                    jsonData.SelectItemID   = table.concat(selected, ",")
                    callback(jsonData)
                end, 2)
            end

            -- 选中
            if selectAble(item) then
                local imageS    = ccui.ImageView:create()
                imageBG:addChild(imageS)
                imageS:loadTexture(global.MMO.PATH_RES_PUBLIC .. "1900000678_2.png")
                imageS:ignoreContentAdaptWithSize(true)
                imageS:setCapInsets(cc.rect(0, 0, 0, 0))
                imageS:setScale9Enabled(false)
                imageS:setTouchEnabled(false)
                imageS:setAnchorPoint(cc.p(0.5,0.5))
                imageS:setPosition(cc.p(size.width/2, size.height/2))
                imageS:setScaleX(itemscaleX)
                imageS:setScaleY(itemscaleY)
            end

            if dblink and string.len(dblink) then
                goodsItem:addDoubleEventListener(function()
                    local jsonData          = {}
                    jsonData.Act            = dblink
                    jsonData.SelectItemID   = item.MakeIndex
                    callback(jsonData)
                end)
            end
        end
    end

    return widget
end

function SUILoader:load_render_EQUIPITEMS(swidget, callback)
    local element               = swidget.element
    local positions             = element.attr.positions or "*"
    local select                = element.attr.select or ""
    local count                 = tonumber(element.attr.count) or 12
    local row                   = tonumber(element.attr.row) or 2
    local selecttype            = tonumber(element.attr.selecttype) or 0
    local showstar              = tonumber(element.attr.showstar) == 1
    local iwidth                = tonumber(element.attr.iwidth) or 70
    local iheight               = tonumber(element.attr.iheight) or 70
    local iimg                  = element.attr.iimg
    local link                  = element.attr.link
    local effectshow            = tonumber(element.attr.effectshow) or 1 -- 1只显示背包 2只显示内观 0不显示

    local itemscaleX            = iwidth / 70
    local itemscaleY            = iheight / 70

    -- 装备位
    local equipPositions        = {}
    local slices                = ssplit(positions, ",")
    for _, v in ipairs(slices) do
        tinsert(equipPositions, tonumber(v))
    end

    -- 是否选中
    local selects               = {}
    local slices                = ssplit(select, ",")
    for _, v in pairs(slices) do
        tinsert(selects, tonumber(v))
    end
    local function selectAble(item)
        for _, v in pairs(selects) do
            if v == item.MakeIndex then
                return true
            end
        end
        return false
    end


    local itemWid               = iwidth
    local itemHei               = iheight
    local col                   = math.ceil(count / row)
    local contentSize           = cc.size(col * itemWid, row * itemHei)

    local widget                = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    --
    local boxes = {}
    for i = 1, count do
        local x                 = ((i - 1) % col + 0.5) * itemWid
        local y                 = contentSize.height - (mfloor((i - 1) / col) + 0.5) * itemHei
        local iimg              = (iimg and iimg ~= "") and SUIHelper.fixImageFileName(iimg) or "public/1900000664.png"
        local fullPath          = string.format(getResFullPath("res/%s"), iimg)
        local imageBG           = ccui.ImageView:create()
        widget:addChild(imageBG)
        imageBG:loadTexture(fullPath)
        GUI:Image_setScale9Slice(imageBG, 21, 22, 21, 22)
            GUI:setContentSize(imageBG, itemWid, itemHei)
        imageBG:setTouchEnabled(false)
        imageBG:setAnchorPoint(cc.p(0.5, 0.5))
        imageBG:setPosition(cc.p(x, y))
        tinsert(boxes, imageBG)
    end

    -- items
    local items                 = {}
    local EquipProxy            = global.Facade:retrieveProxy(global.ProxyTable.Equip)
    if positions == "*" then
        local equipTypeConfig   = EquipProxy:GetEquipTypeConfig()
        for equipPos = equipTypeConfig.Equip_Type_Dress, equipTypeConfig.Equip_Type_Shield do
            local equipData     = EquipProxy:GetEquipDataByPos(equipPos)
            if equipData then
                tinsert(items, equipData)
            end
        end
    else
        for _, equipPos in ipairs(equipPositions) do
            local equipData     = EquipProxy:GetEquipDataByPos(equipPos)
            if equipData then
                tinsert(items, equipData)
            end
        end
    end

    -- show
    for index, item in ipairs(items) do
        local imageBG           = boxes[index]
        if imageBG then
            local size          = imageBG:getContentSize()

            -- 道具图标
            local info = {index = item.Index, itemData = item, starLv = showstar}
            if effectshow == 2 then
                info.showModelEffect = true
            elseif effectshow == 0 then
                info.isShowEff = false
            end
            local goodsItem     = GoodsItem:create(info)
            imageBG:addChild(goodsItem)
            goodsItem:setPosition(cc.p(size.width/2, size.height/2))
            goodsItem._canLooks = true
            goodsItem:addLookItemInfoEvent(nil, 1)
            goodsItem:setScaleX(itemscaleX)
            goodsItem:setScaleY(itemscaleY)
            
            -- link
            if link and string.len(link) > 0 then
                goodsItem:addTouchEventListener(function()
                    local selected          = clone(selects)
                    if selecttype == 0 then
                        -- 多选
                        if selectAble(item) then
                            for key, value in pairs(selected) do
                                if item.MakeIndex == value then
                                    table.remove(selected, key)
                                    break
                                end
                            end
                        else
                            tinsert(selected, item.MakeIndex)
                        end
                    else
                        -- 单选
                        if selectAble(item) then
                            selected = {}
                        else
                            selected = {item.MakeIndex}
                        end
                    end

                    local jsonData          = {}
                    jsonData.Act            = link
                    jsonData.SelectItemID   = table.concat(selected, ",")
                    callback(jsonData)
                end, 2)
            end

            -- 选中
            if selectAble(item) then
                local imageS    = ccui.ImageView:create()
                imageBG:addChild(imageS)
                imageS:loadTexture(global.MMO.PATH_RES_PUBLIC .. "1900000678_2.png")
                imageS:ignoreContentAdaptWithSize(true)
                imageS:setCapInsets(cc.rect(0, 0, 0, 0))
                imageS:setScale9Enabled(false)
                imageS:setTouchEnabled(false)
                imageS:setAnchorPoint(cc.p(0.5,0.5))
                imageS:setPosition(cc.p(size.width/2, size.height/2))
                imageS:setScaleX(itemscaleX)
                imageS:setScaleY(itemscaleY)
            end
        end
    end

    return widget
end

function SUILoader:load_render_TIMETIPS(swidget, callback)
    local element           = swidget.element
    local size              = tonumber(element.attr.size) or defaultFontSize
    local color             = tonumber(element.attr.color) or defaultColorID
    local time              = tonumber(element.attr.time) or 0
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local link              = element.attr.link

    local widget            = ccui.Text:create()
    widget:setString("")
    widget:setFontSize(size)
    widget:setFontName(defaultFontPath)
    widget:setTextColor(GET_COLOR_BYID_C3B(color))
    widget:enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)

    local endTime           = time + GetServerTime()
    local function scheduleCB()
        local remaining = math.max(endTime - GetServerTime(), 0)
        widget:setString(SecondToHMS(remaining, true))
        if remaining <= 0 then
            -- link
            if link and string.len(link) > 0 then
                if callback then
                    local jsonData = {}
                    jsonData.Act   = link
                    callback(jsonData)
                end
            end
            widget:stopAllActions()
        end
    end
    schedule(widget, scheduleCB, 1)
    scheduleCB()
   
    return widget
end

function SUILoader:load_render_LoadingBar(swidget, callback)
    local element           = swidget.element
    local size              = tonumber(element.attr.size) or defaultFontSize
    local color             = tonumber(element.attr.color) or defaultColorID
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local direction         = tonumber(element.attr.direction) or 0   -- 0从左至右  1从右到左
    local loadBgImg         = element.attr.loadingbg or "public/bg_szjm_03_1.png"
    local loadBarImg        = element.attr.loadingbar or "public/bg_szjm_03_2.png"
    local startPercent      = tonumber(element.attr.startper) or 0
    local interval          = tonumber(element.attr.interval) or 0.05
    local loadValue         = tonumber(element.attr.loadvalue) or 10
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local offsetX           = element.attr.offsetX or 0
    local offsetY           = element.attr.offsetY or 0
    local endPercent        = tonumber(element.attr.endper) or 100

    local imgBg             = SUIHelper.fixImageFileName(loadBgImg)
    local imgBar            = SUIHelper.fixImageFileName(loadBarImg)
    local fullPathBG        = (imgBg and imgBg ~= "") and string.format(getResFullPath("res/%s"), imgBg) or ""
    local fullPathBAR       = (imgBar and imgBar ~= "") and string.format(getResFullPath("res/%s"), imgBar) or ""  

    local widget = ccui.ImageView:create()
    widget:ignoreContentAdaptWithSize(false)
    if fullPathBG and  fullPathBG ~= "" and global.FileUtilCtl:isFileExist(fullPathBG) then
        widget:loadTexture(fullPathBG)
    end

    local LoadingBar = ccui.LoadingBar:create()
    if fullPathBAR and fullPathBAR ~= "" and global.FileUtilCtl:isFileExist(fullPathBAR) then
        LoadingBar:loadTexture(fullPathBAR)
    end
    LoadingBar:ignoreContentAdaptWithSize(false)
    LoadingBar:setPercent(startPercent)
    if direction == 1 then
        LoadingBar:setDirection(1)
    end
    LoadingBar:setPosition(cc.p(widget:getContentSize().width/2 + offsetX, widget:getContentSize().height/2 + offsetY))
    widget:addChild(LoadingBar)

    local percentText = ccui.Text:create()
    percentText:setString(string.format(GET_STRING(1053), startPercent, 100))
    percentText:setAnchorPoint(0.5, 0.5)
    percentText:setPosition(cc.p(widget:getContentSize().width/2, widget:getContentSize().height/2))
    percentText:setFontSize(size)
    percentText:setFontName(defaultFontPath)
    percentText:setTextColor(GET_COLOR_BYID_C3B(color))
    percentText:enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)
    widget:addChild(percentText)

    LoadingBar:stopAllActions()
    local percent   = startPercent
    local function scheduleCB()
        percent = percent + loadValue
        
        percent = math.min(percent, endPercent)
        LoadingBar:setPercent(percent)
        local curPercent = mfloor(percent/100 * 100)
        percentText:setString(string.format(GET_STRING(1053), curPercent, 100))

        --
        if percent >= endPercent  then
            LoadingBar:stopAllActions()

            if link and string.len(link) > 0 then
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = link
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end

        end
    end
    schedule(LoadingBar, scheduleCB, interval)
    scheduleCB()

    return widget
end

function SUILoader:load_render_CircleBar(swidget, callback)
    local element           = swidget.element
    local loadBgImg         = element.attr.loadingbg or "private/sui/bg_xbzy_02.png"
    local loadBarImg        = element.attr.loadingbar or "private/sui/bg_xbzy_03.png"
    local startPercent      = tonumber(element.attr.startper) or 0
    local endPercent        = tonumber(element.attr.endper) or 100
    local time              = tonumber(element.attr.time) or 1
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local offsetX           = element.attr.offsetX or 0
    local offsetY           = element.attr.offsetY or 0

    local imgBg             = SUIHelper.fixImageFileName(loadBgImg)
    local imgBar            = SUIHelper.fixImageFileName(loadBarImg)
    local fullPathBG        = (imgBg and imgBg ~= "") and string.format(getResFullPath("res/%s"), imgBg) or ""
    local fullPathBAR       = (imgBar and imgBar ~= "") and string.format(getResFullPath("res/%s"), imgBar) or ""  

    local widget = ccui.ImageView:create()
    widget:ignoreContentAdaptWithSize(false)
    if fullPathBG and fullPathBG ~= "" and global.FileUtilCtl:isFileExist(fullPathBG) then
        widget:loadTexture(fullPathBG)
    end

    local contentSize = widget:getContentSize()
    if fullPathBAR and fullPathBAR ~= "" and global.FileUtilCtl:isFileExist(fullPathBAR) then
        local loadingBar = cc.ProgressTimer:create(cc.Sprite:create(fullPathBAR))
        widget:addChild(loadingBar)
        loadingBar:setPosition(cc.p(contentSize.width / 2 + offsetX, contentSize.height / 2 + offsetY))
        loadingBar:setPercentage(startPercent)
        local function loadEndCallBack()
            loadingBar:stopAllActions()

            if link and string.len(link) > 0 then
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = link
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end
        end
        loadingBar:runAction(
            cc.Sequence:create(
                cc.ProgressFromTo:create(time, startPercent, endPercent),
                cc.DelayTime:create(0.1),
                cc.CallFunc:create(loadEndCallBack)
            )
        )
    end
   
    return widget
end

function SUILoader:load_render_PercentImg(swidget, callback)
    local element           = swidget.element
    local direction         = tonumber(element.attr.direction) or 0  -- 0 从左到右 1从右到左 2从上往下 3从下往上
    local loadImg           = element.attr.img or "public/bg_szjm_03_2.png"
    local minValue          = tonumber(element.attr.minValue) or 100
    local maxValue          = tonumber(element.attr.maxValue) or 100
    local percent           = mfloor( minValue/maxValue * 100) or 100

    local img               = SUIHelper.fixImageFileName(loadImg)
    local fullPath          = (img and img ~= "") and string.format(getResFullPath("res/%s"), img) or ""
   
    local widget = ccui.LoadingBar:create()
    if fullPath and fullPath ~= "" and global.FileUtilCtl:isFileExist(fullPath) then
        widget:loadTexture(fullPath)
    end
    widget:ignoreContentAdaptWithSize(false)

    if direction == 0 or direction == 1 then
        widget:setPercent(percent)
        if direction == 1 then
            widget:setDirection(1)
        end

    elseif direction == 2 or direction == 3 then
        local barRenderer = widget:getVirtualRenderer()
        local barRendererTextureSize = widget:getVirtualRendererSize()
        local innerSprite = barRenderer:getSprite()
        local contentSize = widget:getContentSize()
        widget:setDirection(direction)
        if direction == 2 then
            barRenderer:setAnchorPoint(0, 0)
            barRenderer:setPosition(0, 0)
        else
            barRenderer:setAnchorPoint(0, 1)
            barRenderer:setPosition(0, contentSize.height)
        end
        if innerSprite then
            local rect = innerSprite:getTextureRect()
            rect.height = barRendererTextureSize.height * percent / 100
            innerSprite:setTextureRect(rect, innerSprite:isTextureRectRotated(), cc.size(rect.width, rect.height))
            if direction == 2 then
                innerSprite:setFlippedY(true)
            else
                innerSprite:setFlippedY(false)
            end
        end
    end

    -- 加入元变量组件管理
    local isMateValue = false
    if not tonumber(element.attr.minValue) or not tonumber(element.attr.maxValue) then
        local metaValue = {}
        local content = element.attr.minValue
        while content and string.len(content) > 0 do
            local find_info = {sfind(content, "$STM%((.-)%)")}
            local begin_pos = find_info[1]
            local end_pos   = find_info[2]

            if begin_pos and end_pos then
                isMateValue = true

                -- prefix
                if begin_pos ~= 1 then
                    local substr = string.sub(content, 1, begin_pos - 1)
                    table.insert(metaValue, substr)
                end

                -- metaValue
                local slices = ssplit(find_info[3], "_")
                table.insert(metaValue, {key = slices[1], param = slices[2]})

                -- suffix
                content = string.sub(content, end_pos+1, string.len(content))
            else
                table.insert(metaValue, content)
                content = ""
            end
        end

        local metaValue2 = {}
        local content2 = element.attr.maxValue
        while content2 and string.len(content2) > 0 do
            local find_info = {sfind(content2, "$STM%((.-)%)")}
            local begin_pos = find_info[1]
            local end_pos   = find_info[2]

            if begin_pos and end_pos then
                isMateValue = true

                -- prefix
                if begin_pos ~= 1 then
                    local substr = string.sub(content2, 1, begin_pos - 1)
                    table.insert(metaValue2, substr)
                end

                -- metaValue
                local slices = ssplit(find_info[3], "_")
                table.insert(metaValue2, {key = slices[1], param = slices[2]})

                -- suffix
                content2 = string.sub(content2, end_pos+1, string.len(content))
            else
                table.insert(metaValue2, content2)
                content2 = ""
            end
        end

        if isMateValue then
            widget.useMetaValue = true
            global.Facade:sendNotification(global.NoticeTable.SUIMetaWidgetAdd, {metaValue = metaValue, metaValue2 = metaValue2, widget = widget, lifewidget = widget})
        end
    end

    return widget

end

function SUILoader:load_render_UIModel(swidget,callback)
    local element           = swidget.element
    local sex               = tonumber(element.attr.sex) or 0
    local scale             = tonumber(element.attr.scale) or 1

    local function parseEffectStr(str)
        if not str then
            return nil
        end
        return string.gsub(str, "&", "|")
    end

    local feature           = {}
    feature.clothID         = tonumber(element.attr.clothID)
    feature.weaponID        = tonumber(element.attr.weaponID)
    feature.headID          = tonumber(element.attr.headID)
    feature.headEffectID    = parseEffectStr(element.attr.headEffectID)
    feature.weaponEffectID  = parseEffectStr(element.attr.weaponEffectID)
    feature.clothEffectID   = parseEffectStr(element.attr.clothEffectID)
    feature.capID           = tonumber(element.attr.capID)
    feature.shieldID        = tonumber(element.attr.shieldID)
    feature.shieldEffectID  = parseEffectStr(element.attr.shieldEffectID)
    feature.tDressID        = tonumber(element.attr.tDressID)
    feature.tDressEffectID  = parseEffectStr(element.attr.tDressEffectID)
    feature.tWeaponID       = tonumber(element.attr.tWeaponID)
    feature.tWeaponEffectID = parseEffectStr(element.attr.tWeaponEffectID)
    feature.capEffectID     = parseEffectStr(element.attr.capEffectID)
    feature.veilID          = tonumber(element.attr.veilID)
    feature.veilEffectID    = parseEffectStr(element.attr.veilEffectID)
    feature.hairID          = tonumber(element.attr.hairID)
    feature.notShowMold     = element.attr.notShowMold
    feature.notShowHair     = element.attr.notShowHair

    local UIModel = CreateStaticUIModel(sex, feature, scale, {ignoreStaticScale = true})
    if UIModel then
        return UIModel
    end
end

---- 英雄相关
function SUILoader:load_render_HEROEquipShow(swidget, callback)
    local element           = swidget.element
    local index             = tonumber(element.attr.index) or 0
    local showtips          = tonumber(element.attr.showtips) or 1
    local bgtype            = tonumber(element.attr.bgtype)
    local scale             = tonumber(element.attr.scale) or 1
    local grey              = tonumber(element.attr.grey) or 0
    local showstar          = tonumber(element.attr.showstar) == 1
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local dblink            = element.attr.dblink
    local effectshow        = tonumber(element.attr.effectshow) or 1

    local contentSize       = cc.size(66,66)
   
    local widget            = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
    local HeroEquipProxy = global.Facade:retrieveProxy(global.ProxyTable.HeroEquipProxy)
    local equipData = HeroEquipProxy:GetEquipDataByPos(index)
    if equipData then
        local info          = {}
        info.index          = equipData.Index
        info.itemData       = equipData
        info.look           = showtips == 1
        info.bgVisible      = bgtype == 1
        info.starLv         = showstar
        if not info.look and global.isWinPlayMode then
            info.noMouseTips = true
        end
        if effectshow == 2 then
            info.showModelEffect = true
        elseif effectshow == 0 then
            info.isShowEff = false
        end
        info.from           = ItemMoveProxy.ItemFrom.HERO_EQUIP
        local goodsItem     = GoodsItem:create(info)
        widget:addChild(goodsItem)
        goodsItem:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        goodsItem:setScale(scale)
        goodsItem:setIconGrey(grey == 1)

        if dblink and string.len(dblink) then
            if not (showtips == 1) then
                goodsItem:addLookItemInfoEvent(nil, 2)
            end
            goodsItem:addDoubleEventListener(function()
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = dblink
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    callback(jsonData)
                end
            end)
        end
    end

    if link and not dblink then
        local linkWidget    = global.SWidgetCache:generateRender("ccui.Widget")
        widget:addChild(linkWidget)
        linkWidget:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        linkWidget:setContentSize(contentSize)
        linkWidget:setTouchEnabled(true)
        linkWidget:setSwallowTouches(false)
        linkWidget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end
   
    return widget
end

function SUILoader:load_render_HEROEQUIPITEMS(swidget, callback)
    local element               = swidget.element
    local positions             = element.attr.positions or "*"
    local select                = element.attr.select or ""
    local count                 = tonumber(element.attr.count) or 12
    local row                   = tonumber(element.attr.row) or 2
    local selecttype            = tonumber(element.attr.selecttype) or 0
    local showstar              = tonumber(element.attr.showstar) == 1
    local iwidth                = tonumber(element.attr.iwidth) or 70
    local iheight               = tonumber(element.attr.iheight) or 70
    local iimg                  = element.attr.iimg
    local link                  = element.attr.link
    local effectshow            = tonumber(element.attr.effectshow) or 1

    local itemscaleX            = iwidth / 70
    local itemscaleY            = iheight / 70

    -- 装备位
    local equipPositions        = {}
    local slices                = ssplit(positions, ",")
    for _, v in ipairs(slices) do
        tinsert(equipPositions, tonumber(v))
    end

    -- 是否选中
    local selects               = {}
    local slices                = ssplit(select, ",")
    for _, v in pairs(slices) do
        tinsert(selects, tonumber(v))
    end
    local function selectAble(item)
        for _, v in pairs(selects) do
            if v == item.MakeIndex then
                return true
            end
        end
        return false
    end


    local itemWid               = iwidth
    local itemHei               = iheight
    local col                   = math.ceil(count / row)
    local contentSize           = cc.size(col * itemWid, row * itemHei)

    local widget                = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    --
    local boxes = {}
    for i = 1, count do
        local x                 = ((i - 1) % col + 0.5) * itemWid
        local y                 = contentSize.height - (mfloor((i - 1) / col) + 0.5) * itemHei
        local iimg              = (iimg and iimg ~= "") and SUIHelper.fixImageFileName(iimg) or "public/1900000664.png"
        local fullPath          = string.format(getResFullPath("res/%s"), iimg)
        local imageBG           = ccui.ImageView:create()
        widget:addChild(imageBG)
        imageBG:loadTexture(fullPath)
        GUI:Image_setScale9Slice(imageBG, 21, 22, 21, 22)
            GUI:setContentSize(imageBG, itemWid, itemHei)
        imageBG:setTouchEnabled(false)
        imageBG:setAnchorPoint(cc.p(0.5, 0.5))
        imageBG:setPosition(cc.p(x, y))
        tinsert(boxes, imageBG)
    end

    -- items
    local items                 = {}
    local HeroEquipProxy            = global.Facade:retrieveProxy(global.ProxyTable.HeroEquipProxy)
    if positions == "*" then
        local equipTypeConfig   = HeroEquipProxy:GetEquipTypeConfig()
        for equipPos = equipTypeConfig.Equip_Type_Dress, equipTypeConfig.Equip_Type_Shield do
            local equipData     = HeroEquipProxy:GetEquipDataByPos(equipPos)
            if equipData then
                tinsert(items, equipData)
            end
        end
    else
        for _, equipPos in ipairs(equipPositions) do
            local equipData     = HeroEquipProxy:GetEquipDataByPos(equipPos)
            if equipData then
                tinsert(items, equipData)
            end
        end
    end

    local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
    -- show
    for index, item in ipairs(items) do
        local imageBG           = boxes[index]
        if imageBG then
            local size          = imageBG:getContentSize()

            -- 道具图标
            local info = {index = item.Index, itemData = item, starLv = showstar}
            if effectshow == 2 then
                info.showModelEffect = true
            elseif effectshow == 0 then
                info.isShowEff = false
            end
            info.from           = ItemMoveProxy.ItemFrom.HERO_EQUIP
            local goodsItem     = GoodsItem:create(info)
            imageBG:addChild(goodsItem)
            goodsItem:setPosition(cc.p(size.width/2, size.height/2))
            goodsItem._canLooks = true
            goodsItem:addLookItemInfoEvent(nil, 1)
            goodsItem:setScaleX(itemscaleX)
            goodsItem:setScaleY(itemscaleY)
            
            -- link
            if link and string.len(link) > 0 then
                goodsItem:addTouchEventListener(function()
                    local selected          = clone(selects)
                    if selecttype == 0 then
                        -- 多选
                        if selectAble(item) then
                            for key, value in pairs(selected) do
                                if item.MakeIndex == value then
                                    table.remove(selected, key)
                                    break
                                end
                            end
                        else
                            tinsert(selected, item.MakeIndex)
                        end
                    else
                        -- 单选
                        if selectAble(item) then
                            selected = {}
                        else
                            selected = {item.MakeIndex}
                        end
                    end

                    local jsonData          = {}
                    jsonData.Act            = link
                    jsonData.SelectItemID   = table.concat(selected, ",")
                    callback(jsonData)
                end, 2)
            end

            -- 选中
            if selectAble(item) then
                local imageS    = ccui.ImageView:create()
                imageBG:addChild(imageS)
                imageS:loadTexture(global.MMO.PATH_RES_PUBLIC .. "1900000678_2.png")
                imageS:ignoreContentAdaptWithSize(true)
                imageS:setCapInsets(cc.rect(0, 0, 0, 0))
                imageS:setScale9Enabled(false)
                imageS:setTouchEnabled(false)
                imageS:setAnchorPoint(cc.p(0.5,0.5))
                imageS:setPosition(cc.p(size.width/2, size.height/2))
                imageS:setScaleX(itemscaleX)
                imageS:setScaleY(itemscaleY)
            end
        end
    end

    return widget
end

function SUILoader:load_render_HERODBItemShow(swidget, callback)
    local element           = swidget.element
    local makeindex         = tonumber(element.attr.makeindex)  or 1
    local showtips          = tonumber(element.attr.showtips) or 1
    local bgtype            = tonumber(element.attr.bgtype)
    local scale             = tonumber(element.attr.scale) or 1
    local grey              = tonumber(element.attr.grey) or 0
    local showstar          = tonumber(element.attr.showstar) == 1
    local count             = tonumber(element.attr.count)
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local dblink            = element.attr.dblink
    local effectshow        = tonumber(element.attr.effectshow) or 1

    local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
    local itemData          = nil
    local from              = nil
    if not itemData then
        local HeroEquipProxy    = global.Facade:retrieveProxy(global.ProxyTable.HeroEquipProxy)
        itemData                = HeroEquipProxy:GetEquipDataByMakeIndex(makeindex)
        if itemData then
            from = ItemMoveProxy.ItemFrom.HERO_EQUIP
        end
    end
    if not itemData then
        local HeroBagProxy      = global.Facade:retrieveProxy(global.ProxyTable.HeroBagProxy)
        itemData                = HeroBagProxy:GetItemDataByMakeIndex(makeindex)
        if itemData then
            from = ItemMoveProxy.ItemFrom.HERO_BAG
        end
    end

    if not itemData then
        local LookPlayerProxy = global.Facade:retrieveProxy(global.ProxyTable.LookPlayerProxy)
        itemData = LookPlayerProxy:GetLookPlayerItemDataByMakeIndex(makeindex)
    end

    local contentSize       = cc.size(66,66)
    local widget            = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    if itemData then
        local info          = {}
        info.index          = itemData.Index
        info.itemData       = itemData
        info.look           = showtips == 1
        info.bgVisible      = bgtype == 1
        info.starLv         = showstar
        if not info.look and global.isWinPlayMode then
            info.noMouseTips = true
        end
        if effectshow == 2 then
            info.showModelEffect = true
        elseif effectshow == 0 then
            info.isShowEff = false
        end
        info.from           = from
        local goodsItem     = GoodsItem:create(info)
        widget:addChild(goodsItem)
        goodsItem:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        goodsItem:setScale(scale)
        goodsItem:setIconGrey(grey == 1)
        if count then
            goodsItem:setCount(count)
        end
        if dblink and string.len(dblink) then
            if not (showtips == 1) then
                goodsItem:addLookItemInfoEvent(nil, 2)
            end
            goodsItem:addDoubleEventListener(function()
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = dblink
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end)
        end
    end

    if link and string.len(link) > 0 and not dblink then
        local linkWidget    = global.SWidgetCache:generateRender("ccui.Widget")
        widget:addChild(linkWidget)
        linkWidget:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        linkWidget:setContentSize(contentSize)
        linkWidget:setTouchEnabled(true)
        linkWidget:setSwallowTouches(false)
        linkWidget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end
   
    return widget
end

function SUILoader:load_render_HEROBAGITEMS(swidget, callback)
    local element               = swidget.element
    local condition             = element.attr.condition or ""
    local exclude               = element.attr.exclude or ""
    local select                = element.attr.select or ""
    local count                 = tonumber(element.attr.count) or 12
    local row                   = tonumber(element.attr.row) or 2
    local selecttype            = tonumber(element.attr.selecttype) or 0
    local showstar              = tonumber(element.attr.showstar) == 1
    local iwidth                = tonumber(element.attr.iwidth) or 70
    local iheight               = tonumber(element.attr.iheight) or 70
    local iimg                  = element.attr.iimg
    local filter1               = element.attr.fliter1 or element.attr.filter1 or ""
    local filter2               = element.attr.fliter2 or element.attr.filter2 or ""
    local filter3               = element.attr.fliter3 or element.attr.filter3 or ""
    local link                  = element.attr.link
    local conditionEx           = element.attr.conditionEx
    local conditionParam        = element.attr.conditionParam
    local conditionOnOff        = tonumber(element.attr.conditionOnOff) or 0
    local dblink                = element.attr.dblink
    local effectshow            = tonumber(element.attr.effectshow) or 1

    local itemscaleX            = iwidth / 70
    local itemscaleY            = iheight / 70

    -- 是否满足显示条件
    local conditionT            = {}
    local slices1               = ssplit(condition, ",")
    local slices2               = {}
    for _, v in pairs(slices1) do
        slices2                 = ssplit(v, "#")
        tinsert(conditionT, {StdMode = tonumber(slices2[1]), Shape = tonumber(slices2[2])})
    end
    -- 唯一ID过滤
    local excludeT              = {}
    local slices                = ssplit(exclude, ",")
    for _, v in pairs(slices) do
        tinsert(excludeT, tonumber(v))
    end
   
    -- 道具ID过滤,存在不显示
    local filter1T              = {}
    local slices                = ssplit(filter1, ",")
    for _, v in pairs(slices) do
        tinsert(filter1T, tonumber(v))
    end
   
    -- 道具名过滤,存在不显示
    local filter2T              = {}
    local slices                = ssplit(filter2, ",")
    for _, v in pairs(slices) do
        if v ~= "" then
            tinsert(filter2T, v)
        end
    end

    -- 道具ID过滤,存在才显示
    local filter3T              = {}
    local slices                = ssplit(filter3, ",")
    for _, v in pairs(slices) do
        if v ~= "" then
            tinsert(filter3T, v)
        end
    end

    local function conditionAble(item)
        if conditionEx and tonumber(conditionEx) == 1 then
            local starLv = item.Star or 0
            if conditionOnOff and conditionOnOff == 0 then
                if conditionParam and starLv < tonumber(conditionParam) then
                    return false
                end
            elseif conditionOnOff == 1 then
                if conditionParam and starLv > tonumber(conditionParam) then
                    return false
                end
            end
        end
        -- 被排除
        for _, v in ipairs(excludeT) do
            if v == item.MakeIndex then
                return false
            end
        end

        -- 道具ID过滤
        for _, v in ipairs(filter1T) do
            if v == item.Index then
                return false
            end
        end

        -- 道具名过滤
        for _, v in ipairs(filter2T) do
            if v == item.Name then
                return false
            end
        end

        -- 道具ID/道具名过滤
        if #filter3T > 0 then
            for _, v in ipairs(filter3T) do
                if tonumber(v) == item.Index or v == item.Name then
                    return true
                end
            end
            return false
        end
      
        -- 筛选
        if condition == "*" then
            return true
        end
        for _, v in pairs(conditionT) do
            if v.StdMode == item.StdMode and (not v.Shape or v.Shape == item.Shape) then
                return true
            end
        end
        return false
    end

    -- 是否选中
    local selects               = {}
    local slices                = ssplit(select, ",")
    for _, v in pairs(slices) do
        tinsert(selects, tonumber(v))
    end
    local function selectAble(item)
        for _, v in pairs(selects) do
            if v == item.MakeIndex then
                return true
            end
        end
        return false
    end


    local itemWid               = iwidth
    local itemHei               = iheight
    local col                   = math.ceil(count / row)
    local contentSize           = cc.size(col * itemWid, row * itemHei)

    local widget                = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    --
    local boxes = {}
    for i = 1, count do
        local x                 = ((i - 1) % col + 0.5) * itemWid
        local y                 = contentSize.height - (mfloor((i - 1) / col) + 0.5) * itemHei
        local iimg              = (iimg and iimg ~= "") and SUIHelper.fixImageFileName(iimg) or "public/1900000664.png"
        local fullPath          = string.format(getResFullPath("res/%s"), iimg)
        local imageBG           = ccui.ImageView:create()
        widget:addChild(imageBG)
        imageBG:loadTexture(fullPath)
        GUI:Image_setScale9Slice(imageBG, 21, 22, 21, 22)
            GUI:setContentSize(imageBG, itemWid, itemHei)
        imageBG:setTouchEnabled(false)
        imageBG:setAnchorPoint(cc.p(0.5, 0.5))
        imageBG:setPosition(cc.p(x, y))
        tinsert(boxes, imageBG)
    end

    -- bag items
    local HeroBagProxy          = global.Facade:retrieveProxy(global.ProxyTable.HeroBagProxy)
    local items                 = {}
    for i = 1, global.MMO.MAX_ITEM_NUMBER do
        local itemMakeIndex     = HeroBagProxy:GetMakeIndexByBagPos(i)
        if itemMakeIndex then
            local itemData      = HeroBagProxy:GetItemDataByMakeIndex(itemMakeIndex)
            if itemData and conditionAble(itemData) then
                tinsert(items, itemData)
            end
        end
    end
    --

    local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
    -- show
    for index, item in ipairs(items) do
        local imageBG           = boxes[index]
        if imageBG then
            local size          = imageBG:getContentSize()

            -- 道具图标
            local info = {index = item.Index, itemData = item, starLv = showstar}
            if effectshow == 2 then
                info.showModelEffect = true
            elseif effectshow == 0 then
                info.isShowEff = false
            end
            info.from           = ItemMoveProxy.ItemFrom.HERO_BAG
            local goodsItem     = GoodsItem:create(info)
            imageBG:addChild(goodsItem)
            goodsItem:setPosition(cc.p(size.width/2, size.height/2))
            goodsItem._canLooks = true
            goodsItem:addLookItemInfoEvent(nil, 1)
            goodsItem:setScaleX(itemscaleX)
            goodsItem:setScaleY(itemscaleY)
            
            -- link
            if link and string.len(link) > 0 then
                goodsItem:addTouchEventListener(function()
                    local selected          = clone(selects)
                    if selecttype == 0 then
                        -- 多选
                        if selectAble(item) then
                            for key, value in pairs(selected) do
                                if item.MakeIndex == value then
                                    table.remove(selected, key)
                                    break
                                end
                            end
                        else
                            tinsert(selected, item.MakeIndex)
                        end
                    else
                        -- 单选
                        if selectAble(item) then
                            selected = {}
                        else
                            selected = {item.MakeIndex}
                        end
                    end

                    local jsonData          = {}
                    jsonData.Act            = link
                    jsonData.SelectItemID   = table.concat(selected, ",")
                    callback(jsonData)
                end, 2)
            end

            -- 选中
            if selectAble(item) then
                local imageS    = ccui.ImageView:create()
                imageBG:addChild(imageS)
                imageS:loadTexture(global.MMO.PATH_RES_PUBLIC .. "1900000678_2.png")
                imageS:ignoreContentAdaptWithSize(true)
                imageS:setCapInsets(cc.rect(0, 0, 0, 0))
                imageS:setScale9Enabled(false)
                imageS:setTouchEnabled(false)
                imageS:setAnchorPoint(cc.p(0.5,0.5))
                imageS:setPosition(cc.p(size.width/2, size.height/2))
                imageS:setScaleX(itemscaleX)
                imageS:setScaleY(itemscaleY)
            end

            if dblink and string.len(dblink) then
                goodsItem:addDoubleEventListener(function()
                    local jsonData          = {}
                    jsonData.Act            = dblink
                    jsonData.SelectItemID   = item.MakeIndex
                    callback(jsonData)
                end)
            end
        end
    end

    return widget
end
---

function SUILoader:load_render_QuickTextView(swidget, callback)
    local element           = swidget.element
    local text              = element.attr.text or ""
    local size              = tonumber(element.attr.size) or defaultFontSize
    local color             = element.attr.color or defaultColorID
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local direction         = tonumber(element.attr.direction) or 1
    local bounce            = tonumber(element.attr.bounce) or 1
    local margin            = tonumber(element.attr.margin) or 0
    local width             = tonumber(element.attr.width) or 800
    local height            = tonumber(element.attr.height) or global.Director:getVisibleSize().height
    local count             = tonumber(element.attr.count) or 1

    local function createText( str )
        local item = global.SWidgetCache:generateRender("ccui.Text")
        item:setScale(1)
        item:setString(str)
        item:setFontSize(size)
        item:setFontName(defaultFontPath)
        item:setTextColor(GET_COLOR_BYID_C3B(color))
        item:setTouchEnabled(false)
        item:stopAllActions()
        item:disableEffect(1)
        item:disableEffect(6)
        item:getVirtualRenderer():setMaxLineWidth(0)
        item:enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)

        return item
    end

    local function createItem(loadText, wid, hei)
        local panel =  global.SWidgetCache:generateRender("ccui.Layout")
        panel:setClippingEnabled(true)
        panel:setContentSize(cc.size(wid, hei))
        for i = 1, count do
            if loadText and next(loadText) and loadText[i] then
                local str = loadText[i]
                local item = global.SWidgetCache:generateRender("ccui.Text")
                item:setScale(1)
                item:setString(str)
                item:setFontSize(size)
                item:setFontName(global.MMO.PATH_FONT)
                item:setTextColor(GET_COLOR_BYID_C3B(color))
                item:setTouchEnabled(false)
                item:stopAllActions()
                item:disableEffect(1)
                item:disableEffect(6)
                item:getVirtualRenderer():setMaxLineWidth(0)
                item:enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)
                item:setAnchorPoint(cc.p(0,0))
                item:setPosition(cc.p(wid/count*(i-1), 0))
                panel:addChild(item)
            end
        end
        return panel
    end

    local widget = global.SWidgetCache:generateRender("ccui.ListView")
    widget:ignoreContentAdaptWithSize(false)
    widget:setClippingEnabled(true)
    widget:setClippingType(0)
    widget:setTouchEnabled(true)
    widget:setDirection(direction)
    widget:setGravity(0)
    widget:setItemsMargin(margin)
    widget:setBounceEnabled(bounce == 1)
    widget:setBackGroundColorType(0)
    widget:stopAllActions()

    local textList = string.split(text, "\\")
    local itemHei = 10
    if textList and textList[1] then
        itemHei = createText(textList[1]):getContentSize().height
    end
    local screenHeight = height-- global.Director:getVisibleSize().height
    local limitSize = math.ceil(screenHeight/itemHei)

    local loadText = clone(textList)
    local loadNum = 0
    local function loadItem( ... )
        local lastIndex = #widget:getItems() - 1
        while next(loadText) and loadNum < limitSize do
            loadNum = loadNum + 1
            local cell_data = {}
            cell_data.wid = width
            cell_data.hei = itemHei

            local strList = {}
            for i = 1, count do
                if loadText and next(loadText) then
                    table.insert( strList, table.remove( loadText,1 ))
                end
            end
            cell_data.createCell = function ()
                local cell = createItem(strList, cell_data.wid, cell_data.hei)
                return cell
            end

            local quickCell = QuickCell:Create(cell_data)
            widget:pushBackCustomItem(quickCell)
        end
        if lastIndex >= 0 then
            widget:jumpToItem(lastIndex, cc.p(0, 0), cc.p(0, 0))
        end
    end

    loadItem()
    local loadForce = true
    widget:addScrollViewEventListener(function(sender, eventType)
        local itemNum = #sender:getItems()
        local BottomItem = sender:getBottommostItemInCurrentView()
        local innerPos = widget:getInnerContainerPosition()
        if (eventType ==  1 or ((eventType == 10 or eventType == 9) and innerPos.y == 0)) and next(loadText) then
            loadNum = 0
            if loadForce then
                loadForce = false
                PerformWithDelayGlobal( function()
                    loadForce = true
                end, 0.5 )
                loadItem()
            end
        end
    end)
    widget:addMouseScrollPercent()
    return widget
end

function SUILoader:load_render_RTextX(swidget, callback)
    local element           = swidget.element
    local text              = element.attr.text or ""
    local size              = tonumber(element.attr.size) or defaultFontSize
    local color             = tonumber(element.attr.color) or defaultColorID
    local width             = tonumber(element.attr.width) or 1136
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local scrollWidth       = tonumber(element.attr.scrollWidth)
    local scrollWay         = tonumber(element.attr.scrollWay) or 0         -- 0 从右到左 1 从下到上
    local scrollTime        = tonumber(element.attr.scrollTime) or 4
    local scrollHeight      = tonumber(element.attr.scrollHeight)


    local function textCB(str)
        if callback then
            local jsonData      = {}
            jsonData.Act        = str
            callback(jsonData)
        end
    end
    local ttfConfig = {
        outlineSize = outline,
        outlineColor = GET_COLOR_BYID_C3B(outlinecolor)
    }
    local SUI_RTEXT_FONT_PATH = SL:GetMetaValue("WINPLAYMODE") and SL:GetMetaValue("GAME_DATA","SUI_RTEXT_FONT_PATH") or nil
    local fontPath = SUI_RTEXT_FONT_PATH or defaultFontPath
    local widget = RichTextHelp:CreateRichTextWithXML(text, width, size, GET_COLOR_BYID(color), fontPath, textCB, SL:GetMetaValue("GAME_DATA","DEFAULT_VSPACE"))

    self:addMouseOverTips(widget, element)

    -- auto scroll
    if scrollWidth then
        local widgetSize   = widget:getContentSize()
        local scrollH      = scrollHeight or widgetSize.height
        local scrollLayout = global.SWidgetCache:generateRender("ccui.Layout")
        scrollLayout:setClippingEnabled(true)
        scrollLayout:setClippingType(0)
        scrollLayout:setContentSize(cc.size(scrollWidth, scrollH))
        scrollLayout:addChild(widget)
        widget:setAnchorPoint(cc.p(0, 0))
        widget:setPosition(cc.p(0, 0))
        if scrollWay == 0 then
            widget:runAction(cc.RepeatForever:create(cc.Sequence:create(
                cc.MoveBy:create(scrollTime, cc.p(-widgetSize.width, 0)),
                cc.MoveBy:create(0, cc.p(widgetSize.width, 0)))
            ))
        elseif scrollWay == 1 then
            widget:setAnchorPoint(cc.p(0, 1))
            widget:setPosition(cc.p(0, scrollH))
            widget:runAction(cc.RepeatForever:create(cc.Sequence:create(
                cc.MoveBy:create(scrollTime, cc.p(0, widgetSize.height)),
                cc.MoveBy:create(0, cc.p(0, -widgetSize.height))
            )))
        end
        return scrollLayout
    end

    return widget
end

function SUILoader:load_render_DLINKITEMS(swidget, callback)
    local element               = swidget.element
    local condition             = element.attr.condition or ""
    local exclude               = element.attr.exclude or ""
    local select                = element.attr.select or ""
    local count                 = tonumber(element.attr.count) or 12
    local row                   = tonumber(element.attr.row) or 2
    local selecttype            = tonumber(element.attr.selecttype) or 0
    local showstar              = tonumber(element.attr.showstar) == 1
    local iwidth                = tonumber(element.attr.iwidth) or 70
    local iheight               = tonumber(element.attr.iheight) or 70
    local iimg                  = element.attr.iimg
    local filter1               = element.attr.fliter1 or element.attr.filter1 or ""
    local filter2               = element.attr.fliter2 or element.attr.filter2 or ""
    local filter3               = element.attr.fliter3 or element.attr.filter3 or ""
    local link                  = element.attr.link
    local conditionEx           = element.attr.conditionEx
    local conditionParam        = element.attr.conditionParam
    local conditionOnOff        = tonumber(element.attr.conditionOnOff) or 0
   
    local itemscaleX            = iwidth / 70
    local itemscaleY            = iheight / 70

    -- 是否满足显示条件
    local conditionT            = {}
    local slices1               = ssplit(condition, ",")
    local slices2               = {}
    for _, v in pairs(slices1) do
        slices2                 = ssplit(v, "#")
        tinsert(conditionT, {StdMode = tonumber(slices2[1]), Shape = tonumber(slices2[2])})
    end
    -- 唯一ID过滤
    local excludeT              = {}
    local slices                = ssplit(exclude, ",")
    for _, v in pairs(slices) do
        tinsert(excludeT, tonumber(v))
    end
   
    -- 道具ID过滤,存在不显示
    local filter1T              = {}
    local slices                = ssplit(filter1, ",")
    for _, v in pairs(slices) do
        tinsert(filter1T, tonumber(v))
    end
   
    -- 道具名过滤,存在不显示
    local filter2T              = {}
    local slices                = ssplit(filter2, ",")
    for _, v in pairs(slices) do
        if v ~= "" then
            tinsert(filter2T, v)
        end
    end

    -- 道具ID过滤,存在才显示
    local filter3T              = {}
    local slices                = ssplit(filter3, ",")
    for _, v in pairs(slices) do
        if v ~= "" then
            tinsert(filter3T, v)
        end
    end

    local function conditionAble(item)
        if conditionEx and tonumber(conditionEx) == 1 then
            local starLv = item.Star or 0
            if conditionOnOff and conditionOnOff == 0 then
                if conditionParam and starLv < tonumber(conditionParam) then
                    return false
                end
            elseif conditionOnOff == 1 then
                if conditionParam and starLv > tonumber(conditionParam) then
                    return false
                end
            end
        end
        -- 被排除
        for _, v in ipairs(excludeT) do
            if v == item.MakeIndex then
                return false
            end
        end

        -- 道具ID过滤
        for _, v in ipairs(filter1T) do
            if v == item.Index then
                return false
            end
        end

        -- 道具名过滤
        for _, v in ipairs(filter2T) do
            if v == item.Name then
                return false
            end
        end

        -- 道具ID/道具名过滤
        if #filter3T > 0 then
            for _, v in ipairs(filter3T) do
                if tonumber(v) == item.Index or v == item.Name then
                    return true
                end
            end
            return false
        end
      
        -- 筛选
        if condition == "*" then
            return true
        end
        for _, v in pairs(conditionT) do
            if v.StdMode == item.StdMode and (not v.Shape or v.Shape == item.Shape) then
                return true
            end
        end
        return false
    end

    local itemWid               = iwidth
    local itemHei               = iheight
    local col                   = math.ceil(count / row)
    local contentSize           = cc.size(col * itemWid, row * itemHei)

    local widget                = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    --
    local boxes = {}
    for i = 1, count do
        local x                 = ((i - 1) % col + 0.5) * itemWid
        local y                 = contentSize.height - (mfloor((i - 1) / col) + 0.5) * itemHei
        local iimg              = (iimg and iimg ~= "") and SUIHelper.fixImageFileName(iimg) or "public/1900000664.png"
        local fullPath          = string.format(getResFullPath("res/%s"), iimg)
        local imageBG           = ccui.ImageView:create()
        widget:addChild(imageBG)
        imageBG:loadTexture(fullPath)
        GUI:Image_setScale9Slice(imageBG, 21, 22, 21, 22)
            GUI:setContentSize(imageBG, itemWid, itemHei)
        imageBG:setTouchEnabled(false)
        imageBG:setAnchorPoint(cc.p(0.5, 0.5))
        imageBG:setPosition(cc.p(x, y))
        tinsert(boxes, imageBG)
    end

    -- bag items
    local BagProxy              = global.Facade:retrieveProxy(global.ProxyTable.Bag)
    local items                 = {}
    local BagMaxNum = BagProxy:GetMaxBag()
    for i = 1, BagMaxNum do
        local itemMakeIndex     = BagProxy:GetMakeIndexByBagPos(i)
        if itemMakeIndex then
            local itemData      = BagProxy:GetItemDataByMakeIndex(itemMakeIndex)
            if itemData and conditionAble(itemData) then
                tinsert(items, itemData)
            end
        end
    end
    --

    -- show
    for index, item in ipairs(items) do
        local imageBG           = boxes[index]
        if imageBG then
            local size          = imageBG:getContentSize()

            -- 道具图标
            local goodsItem     = GoodsItem:create({index = item.Index, itemData = item, starLv = showstar,look = true})
            imageBG:addChild(goodsItem)
            goodsItem:setPosition(cc.p(size.width/2, size.height/2))
            goodsItem:setScaleX(itemscaleX)
            goodsItem:setScaleY(itemscaleY)
            
            -- link
            if link and string.len(link) > 0 then
                goodsItem:addDoubleEventListener(function()
                    local jsonData          = {}
                    jsonData.Act            = link
                    jsonData.SelectItemID   = item.MakeIndex
                    callback(jsonData)
                end)
            end
        end
    end

    return widget
end

function SUILoader:load_render_MKItemShow(swidget, callback)
    local element           = swidget.element
    local makeindex         = tonumber(element.attr.makeindex)  or 1
    local showtips          = tonumber(element.attr.showtips) or 1
    local bgtype            = tonumber(element.attr.bgtype)
    local scale             = tonumber(element.attr.scale) or 1
    local grey              = tonumber(element.attr.grey) or 0
    local showstar          = tonumber(element.attr.showstar) == 1
    local count             = tonumber(element.attr.count)
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local canmove           = tonumber(element.attr.canmove) or 0
    local effectshow        = tonumber(element.attr.effectshow) or 1 -- 1只显示背包 2只显示内观 0不显示

    local itemData          = nil
    if not itemData then
        local PetsEquipProxy = global.Facade:retrieveProxy(global.ProxyTable.PetsEquipProxy)
        itemData             = PetsEquipProxy:GetEquipDataByMakeIndex(makeindex)
    end

    -- 人物
    if not itemData then
        local EquipProxy    = global.Facade:retrieveProxy(global.ProxyTable.Equip)
        itemData            = EquipProxy:GetEquipDataByMakeIndex(makeindex)
    end
    if not itemData then
        local BagProxy      = global.Facade:retrieveProxy(global.ProxyTable.Bag)
        itemData            = BagProxy:GetItemDataByMakeIndex(makeindex)
    end
    -- 英雄
    if not itemData then
        local HeroEquipProxy    = global.Facade:retrieveProxy(global.ProxyTable.HeroEquipProxy)
        itemData                = HeroEquipProxy:GetEquipDataByMakeIndex(makeindex)
    end
    if not itemData then
        local HeroBagProxy      = global.Facade:retrieveProxy(global.ProxyTable.HeroBagProxy)
        itemData                = HeroBagProxy:GetItemDataByMakeIndex(makeindex)
    end

    local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
    local contentSize       = cc.size(66,66)
    local widget            = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)

    if itemData then
        local info          = {}
        info.index          = itemData.Index
        info.itemData       = itemData
        -- info.look           = showtips == 1
        info.bgVisible      = bgtype == 1
        info.starLv         = showstar
        info.from           = ItemMoveProxy.ItemFrom.PETS_EQUIP
        info.movable        = false
        if effectshow == 2 then
            info.showModelEffect = true
        elseif effectshow == 0 then
            info.isShowEff = false
        end
        local goodsItem     = GoodsItem:create(info)
        widget:addChild(goodsItem)
        goodsItem:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        goodsItem:setScale(scale)
        goodsItem:setIconGrey(grey == 1)
        if count then
            goodsItem:setCount(count)
        end
        
        local function linkFunc()
            if link and string.len(link) > 0 then
                local jsonData          = {}
                jsonData.Act            = link
                jsonData.SelectItemID   = itemData.MakeIndex
                if callback then
                    callback(jsonData)
                end
            end
        end

        local itemMoveState = {
            begin = 1,
            moving = 2,
            end_move = 3,
        }

        local function SetGoodItemState(state, movePos)
            if not itemData then
                return
            end

            if itemMoveState.begin == state then
                if widget and not tolua.isnull(widget) then
                    widget._movingState = true
                    widget:setVisible(false)
                end
                global.Facade:sendNotification(global.NoticeTable.Layer_ItemTips_Close)
                global.Facade:sendNotification(global.NoticeTable.Layer_Moved_Begin,{
                    pos = movePos,
                    itemData = itemData,
                    linkFunc  = linkFunc,
                    cancelCallBack = function()
                        if widget and not tolua.isnull(widget) then
                            widget._movingState = false
                            widget:setVisible(true)
                        end
                    end,
                    from = ItemMoveProxy.ItemFrom.PETS_EQUIP
                })
            elseif itemMoveState.moving == state then
        
            elseif itemMoveState.end_move == state then
                global.Facade:sendNotification(global.NoticeTable.Layer_Moved_End, movePos)
            end
        end

        local function doubleEventCallBack()
            local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
            local itemMoving = ItemMoveProxy:GetMovingItemState()
            if itemMoving then --在道具移动中
                return
            end
            if itemData then
                linkFunc()
            end
        end

        local function clickEventCallBack(widget, eventtype)
            if tolua.isnull(widget) then
                return
            end
            local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
            
            if not itemData or widget._movingState then
                return
            end
            local panelPos = widget:getWorldPosition()
            if global.isWinPlayMode and canmove == 1 then
                SetGoodItemState(itemMoveState.begin, panelPos)
            else
                if showtips == 1 then
                    local data = {}
                    data.itemData = itemData
                    data.pos = panelPos
                    data.from = ItemMoveProxy.ItemFrom.PETS_EQUIP
                    global.Facade:sendNotification(global.NoticeTable.Layer_ItemTips_Open, data)
                end
            end
        end

        local pressEventCallBack = clickEventCallBack

        local isEventPress = false
        local isMoved = true
        local hasEventCallOnTouchBegin = false        --只有在响应了touchbegin 时才会去响应延时方法 因为在延时后 鼠标事件的 状态已经被置掉
        local isMobile = not global.isWinPlayMode

        local function delayCallback()
            isEventPress = true
   
            if pressEventCallBack then
                if not pressEventCallBack then
                    return false
                end
   
                if not isMoved then
                    pressEventCallBack()
                    return false
                end
   
                local movedPos = widget:getTouchMovePosition()
                local beganPos = widget:getTouchBeganPosition()
   
                local diff = cc.pSub(movedPos, beganPos)
                local distSq = cc.pLengthSQ(diff)
                if distSq <= 100 then
                    pressEventCallBack()
                end
            end
        end

        local function touchEvent( touch, eventType )
            if global.OperatingMode == global.MMO.OPERATING_MODE_WINDOWS then
                local ItemMoveProxy = global.Facade:retrieveProxy(global.ProxyTable.ItemMoveProxy)
                local itemMoving = ItemMoveProxy:GetMovingItemState()
                if itemMoving then --在道具移动中
                    return
                end
            end
            if eventType == 0 then
                isEventPress = false
                isMoved = false
                hasEventCallOnTouchBegin = true
   
                if pressEventCallBack then
                    performWithDelay(widget, delayCallback, global.MMO.CLICK_DOUBLE_TIME)
                end
            elseif eventType == 1 then
                local movedPos = widget:getTouchMovePosition()
                local beganPos = widget:getTouchBeganPosition()

                local diff = cc.pSub(movedPos, beganPos)
                local distSq = cc.pLengthSQ(diff)
                if not isMoved and distSq > 100 then
                    isMoved = true
                    if isMobile and canmove == 1 then
                        local beginMovePos = widget:getWorldPosition()
                        SetGoodItemState(itemMoveState.begin, beginMovePos)
                    end
                end
                if isMobile then
                    local movedPos = widget:getTouchMovePosition()
                    global.Facade:sendNotification(global.NoticeTable.Layer_Moved_Moving,{pos = movedPos})
                end
            elseif eventType == 2 then
                widget:stopAllActions()
   
                if not isMoved then
                    if not isEventPress then
                        -- 判断是否有双击事件
                        if doubleEventCallBack then
                            -- 记录上一次点击时间
                            if not widget._lastClickTime then
                                widget._lastClickTime = true
                                -- 记录单击触发
                                -- 记录进入此处时的状态,避免在延时操作后状态被改变
                                local stateOnbegin = hasEventCallOnTouchBegin
                                widget._clickDelayHandler =
                                    PerformWithDelayGlobal(
                                    function()
                                        if clickEventCallBack and stateOnbegin then
                                            clickEventCallBack(widget, eventType)
                                        end
   
                                        widget._lastClickTime = nil
                                    end,
                                    global.MMO.CLICK_DOUBLE_TIME
                                )
                            else
                                if widget._clickDelayHandler then
                                    UnSchedule(widget._clickDelayHandler)
                                    widget._clickDelayHandler = nil
                                end
   
                                if doubleEventCallBack then
                                    doubleEventCallBack()
                                end
   
                                widget._lastClickTime = nil
                            end
                        else
                            if clickEventCallBack then
                                clickEventCallBack(widget, eventType)
                            end
                        end
                    end
                else
                    if isMobile and canmove == 1 then
                        local endPos = widget:getTouchEndPosition()
                        SetGoodItemState(itemMoveState.end_move, endPos)
                    end
                end
                hasEventCallOnTouchBegin = false
            elseif eventType == 3 then
                if isMobile and canmove == 1 then
                    local endPos = widget:getTouchEndPosition()
                    SetGoodItemState(itemMoveState.end_move, endPos)
                end
                hasEventCallOnTouchBegin = false
            end
        end
        widget:setTouchEnabled(true)
        widget:addTouchEventListener( touchEvent )

    end

    return widget
end

function SUILoader:load_render_PETEQUIPSHOW(swidget, callback)
    local element           = swidget.element
    local index             = tonumber(element.attr.index) or 0
    local showtips          = tonumber(element.attr.showtips) or 1
    local bgtype            = tonumber(element.attr.bgtype)
    local scale             = tonumber(element.attr.scale) or 1
    local grey              = tonumber(element.attr.grey) or 0
    local showstar          = tonumber(element.attr.showstar) == 1
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local dblink            = element.attr.dblink

    local contentSize       = cc.size(66,66)
    local widget            = global.SWidgetCache:generateRender("ccui.Widget")
    widget:setContentSize(contentSize)


    local PetsEquipProxy    = global.Facade:retrieveProxy(global.ProxyTable.PetsEquipProxy)
    local curSelectPetIdx   = PetsEquipProxy:GetSelectPetIdx()
    local equipData         = PetsEquipProxy:GetEquipDataByPos(curSelectPetIdx, index)
    if equipData then
        local info          = {}
        info.index          = equipData.Index
        info.itemData       = equipData
        info.look           = showtips == 1
        info.bgVisible      = bgtype == 1
        info.starLv         = showstar
        if not info.look and global.isWinPlayMode then
            info.noMouseTips = true
        end
        local goodsItem     = GoodsItem:create(info)
        widget:addChild(goodsItem)
        goodsItem:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        goodsItem:setScale(scale)
        goodsItem:setIconGrey(grey == 1)

        if dblink and string.len(dblink) then
            if not (showtips == 1) then
                goodsItem:addLookItemInfoEvent(nil, 2)
            end
            goodsItem:addDoubleEventListener(function()
                if callback then
                    local inputTable    = self:getInputTable(submitInput)
                    local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                    local jsonData      = {}
                    jsonData.Act        = dblink
                    jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                    jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                    self:linkFuncWithCheckWords(callback, jsonData)
                end
            end)
        end
    end

    if link and not dblink then
        local linkWidget    = global.SWidgetCache:generateRender("ccui.Widget")
        widget:addChild(linkWidget)
        linkWidget:setPosition(cc.p(contentSize.width/2, contentSize.height/2))
        linkWidget:setContentSize(contentSize)
        linkWidget:setTouchEnabled(true)
        linkWidget:setSwallowTouches(false)
        linkWidget:addClickEventListener(function()
            if callback then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end)
    end

    return widget
end

function SUILoader:load_render_PageView(swidget, callback)
    local element           = swidget.element
    local width             = element.attr.width or 200
    local height            = element.attr.height or 200
    local color             = tonumber(element.attr.color)
    -- local direction         = tonumber(element.attr.direction) or 2
    local default           = tonumber(element.attr.default)
    local cantouch          = tonumber(element.attr.cantouch) or 1

    local widget = ccui.PageView:create()
    widget:ignoreContentAdaptWithSize(false)
    widget:setClippingEnabled(true)
    widget:setClippingType(0)
    widget:setTouchEnabled(true)
    -- widget:setDirection(direction)
    widget:setBackGroundColorType(0)
    widget:stopAllActions()

    if DEBUG_MODE then
        widget:setBackGroundColorType(1)
        widget:setBackGroundColorOpacity(100)
        widget:setBackGroundColor(cc.Color3B.GREEN)
    end

    -- color
    if color then
        widget:setBackGroundColorType(1)
        widget:setBackGroundColorOpacity(255)
        widget:setBackGroundColor(GET_COLOR_BYID_C3B(color))
    end

    -- default
    if default then
        -- default
        local function callback()
            default = default - 1
            local index = math.max(default, 0)
            widget:setCurrentPageIndex(index)
            widget:doLayout()
        end
        performWithDelay(widget, callback, 1/60)
    end

    if cantouch == 0 then
        widget:setTouchEnabled(false)
    end
   
    return widget
end

function SUILoader:load_render_Slider(swidget, callback)
    local element       = swidget.element
    local sliderid      = element.attr.sliderid
    local ballPath      = element.attr.ballimg or "public/bg_szjm_02_1.png"
    local barPath       = element.attr.barimg or "public/bg_szjm_02.png"
    local bgPath        = element.attr.bgimg or "public/bg_szjm_01.png"
    local default       = tonumber(element.attr.defvalue) or 0
    local maxValue      = tonumber(element.attr.maxvalue) or 100
    local link          = element.attr.link

    local SUIComponentProxy = global.Facade:retrieveProxy(global.ProxyTable.SUIComponentProxy)

    local defaultPer    = mfloor(default)

    ballPath = SUIHelper.fixImageFileName(ballPath)
    barPath = SUIHelper.fixImageFileName(barPath)
    bgPath = SUIHelper.fixImageFileName(bgPath)

    local widget = ccui.Slider:create()
    widget:loadBarTexture(string.format(getResFullPath("res/%s"), bgPath), 0)
    widget:loadProgressBarTexture(string.format(getResFullPath("res/%s"), barPath), 0)
    widget:loadSlidBallTextureNormal(string.format(getResFullPath("res/%s"), ballPath), 0)
   
    widget:ignoreContentAdaptWithSize(false)
    widget:setTouchEnabled(true)

    widget:setMaxPercent(maxValue)
    widget:setPercent(defaultPer)
    widget:addEventListener(function(_, eventType)
        if eventType == 0 then
            local per = widget:getPercent()
            local curValue = mfloor(per)
            if self._sliderWidgets[sliderid] then
                self._sliderWidgets[sliderid].value = curValue
            end
            SUIComponentProxy:SetSUISliderValueById(sliderid, curValue)
            global.Facade:sendNotification(global.NoticeTable.SUISlider_Value_Change)
            
        elseif eventType == 2 then
            if callback then
                local sliderTable   = self:getSliderTableByID(sliderid)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Slider     = (#sliderTable > 0 and sliderTable or nil)
                callback(jsonData)
            end
        end
    end)

    if sliderid and self._sliderWidgets then
        self._sliderWidgets[sliderid] = {
            widget = widget,
            value = default
        }
        SUIComponentProxy:SetSUISliderValueById(sliderid, default)
        global.Facade:sendNotification(global.NoticeTable.SUISlider_Value_Change)
    end

    return widget
end

local function fixPosition(p)
    if not p then
        return nil
    end
    if tonumber(p) then
        return mfloor(p)
    end
    return cc.p(mfloor(p.x), mfloor(p.y))
end

function SUILoader:load_render_MenuItem(swidget, callback)
    local element       = swidget.element
    local menuid        = element.attr.menuid
    local imgPath       = element.attr.img or "public/1900000668.png"
    local arrowPath     = element.attr.arrowimg or "public/btn_szjm_01.png"
    local listPath      = element.attr.listimg or "public/1900000677.png"
    local itemname      = element.attr.itemname
    local select        = element.attr.select or ""
    local selectimg     = element.attr.selectimg or "public/1900000678.png"
    local direction     = tonumber(element.attr.direction) or 0  -- 默认0下拉 1上拉
    local width         = tonumber(element.attr.width)  
    local height        = tonumber(element.attr.height)
    local itemHei       = tonumber(element.attr.itemhei) or 16
    local fontSize      = tonumber(element.attr.fontsize) or 14
    local fontColor     = tonumber(element.attr.fontcolor) or 255
    local selectColor   = tonumber(element.attr.selectcolor)
    local maxHei        = tonumber(element.attr.maxhei)
    local link          = element.attr.link

    local itemList = {}
    if itemname and string.len(itemname) > 0 then
        itemList = string.split(itemname, "#")
    end
    local selectPath = string.format(getResFullPath("res/%s"), SUIHelper.fixImageFileName(selectimg))
    imgPath = string.format(getResFullPath("res/%s"), SUIHelper.fixImageFileName(imgPath))
    arrowPath = string.format(getResFullPath("res/%s"), SUIHelper.fixImageFileName(arrowPath))
    listPath = string.format(getResFullPath("res/%s"), SUIHelper.fixImageFileName(listPath))

    -- 默认显示选项
    local widget = ccui.ImageView:create()
    widget:loadTexture(imgPath)
    widget:ignoreContentAdaptWithSize(false)
    if not width then
        width = widget:getVirtualRendererSize().width
    end
    if not height then
        height = widget:getVirtualRendererSize().height
    end
    widget:setContentSize(cc.size(width, height))

    local arrow = ccui.ImageView:create()
    arrow:loadTexture(arrowPath)
    arrow:setAnchorPoint(cc.p(1, 0.5))
    arrow:setPosition(fixPosition(cc.p(width - 6, height / 2)))
    arrow:setFlippedY(direction == 0)
    arrow:addTo(widget)

    local showText = ccui.Text:create()
    showText:setAnchorPoint(cc.p(0.5, 0.5))
    showText:setPosition(fixPosition(cc.p(width / 2, height / 2)))
    showText:setFontName(global.MMO.PATH_FONT)
    showText:setFontSize(fontSize)
    showText:setTextColor(GET_COLOR_BYID_C3B(fontColor))
    showText:setString(select)
    showText:addTo(widget)

    if not next(itemList) then
        return widget
    end

    local menuListView = nil
    local itemCells = {}
    local isOpen = false

    local function onRefreshSelect()
        for _, cell in ipairs(itemCells) do
            local titleText = cell.title
            local selectImg = cell.selectImg
            if titleText and selectImg then
                local name = titleText:getString()
                if select and name == select then
                    selectImg:setVisible(true)
                    if selectColor then
                        titleText:setTextColor(GET_COLOR_BYID_C3B(selectColor))
                    end
                else
                    selectImg:setVisible(false)
                    titleText:setTextColor(GET_COLOR_BYID_C3B(fontColor))
                end
            end
        end
        showText:setString(select)
        arrow:setFlippedY(direction == 0)
        if widget:getChildByTag(777) then
            widget:removeChildByTag(777)
            isOpen = false
        end
    end

    local function showItemList()
        isOpen = not isOpen
        if widget:getChildByTag(777) then
            widget:removeChildByTag(777)
        end
        if not isOpen then
            arrow:setFlippedY(direction == 0)
            return
        end
        arrow:setFlippedY(direction ~= 0)

        local num = #itemList
        local menuListBg = ccui.ImageView:create()
        menuListBg:loadTexture(listPath)
        menuListBg:ignoreContentAdaptWithSize(false)
        menuListBg:setScale9Enabled(true)
        menuListBg:setCapInsets({x = 21, y = 33, width = 23, height = 34})
        local aPoint = direction == 0 and cc.p(0, 1) or cc.p(0, 0)
        menuListBg:setAnchorPoint(aPoint)
        local posX = width * (0 - widget:getAnchorPoint().x)
        local posY = direction == 0 and height * (0 - widget:getAnchorPoint().y) or height * (1 - widget:getAnchorPoint().y)
        local posY = direction == 0 and 0 or height
        menuListBg:setPosition(fixPosition(cc.p(0, posY)))
        menuListBg:setTag(777)
        widget:addChild(menuListBg)
        
        menuListView = ccui.ListView:create()
        menuListBg:addChild(menuListView)
        menuListView:setPosition(fixPosition(cc.p(width/2, 3)))
        menuListView:setAnchorPoint(cc.p(0.5, 0))
        menuListView:setContentSize(cc.size(width, 0))
        menuListView:setClippingEnabled(true)
        menuListView:setClippingType(0)
        menuListView:setTouchEnabled(true)
        menuListView:setDirection(1)
   
        for id, name in ipairs(itemList) do
            if string.len(name) > 0 then
                local channel_cell = ccui.Layout:create()
                channel_cell:setContentSize(cc.size(width, itemHei))

                local selectImg = ccui.ImageView:create()
                selectImg:setPosition(fixPosition(cc.p(width/2, itemHei/2)))
                selectImg:loadTexture(selectPath)
                selectImg:ignoreContentAdaptWithSize(false)
                selectImg:setContentSize(cc.size(width, itemHei))
                selectImg:addTo(channel_cell)

                local titleText = ccui.Text:create()
                titleText:setAnchorPoint(cc.p(0.5, 0.5))
                titleText:setPosition(fixPosition(cc.p(width/2, itemHei/2)))
                titleText:setFontName(global.MMO.PATH_FONT)
                titleText:setFontSize(fontSize)
                titleText:setString(name)
                titleText:addTo(channel_cell)

                if select and name == select then
                    selectImg:setVisible(true)
                    if selectColor then
                        titleText:setTextColor(GET_COLOR_BYID_C3B(selectColor))
                    end
                else
                    selectImg:setVisible(false)
                    titleText:setTextColor(GET_COLOR_BYID_C3B(fontColor))
                end
                channel_cell:setTouchEnabled(true)
                channel_cell:addClickEventListener(function()
                    select = name
                    onRefreshSelect()
                    if callback then
                        local menuTable     = self:getMenuItemTableByID(menuid)
                        local jsonData      = {}
                        jsonData.Act        = link
                        jsonData.MenuItem   = (#menuTable > 0 and menuTable or nil)
                        callback(jsonData)
                    end
                end)
                menuListView:pushBackCustomItem(channel_cell)

                itemCells[id] = {cell = channel_cell, title = titleText, selectImg = selectImg}
            end
        end

        local count = #menuListView:getChildren()
        local listWid = menuListView:getContentSize().width
        local rHei = count * itemHei
        local listHei = maxHei and math.min(rHei, maxHei) or rHei
        menuListView:setContentSize(cc.size(listWid, listHei))
        menuListBg:setContentSize(cc.size(listWid + 4, listHei + 6))
    end

    widget:setTouchEnabled(true)
    widget:addClickEventListener(function ()
        DelayTouchEnabled(widget)
        showItemList()
    end)

    if menuid and self._menuItemWidgets then
        self._menuItemWidgets[menuid] = {
            widget = showText,
            value = select
        }
    end
        
    return widget
end

function SUILoader:load_render_ScrapePic(swidget, callback)
    local element           = swidget.element
    local showImg           = element.attr.showimg                          -- 展示图片
    local maskImg           = element.attr.maskimg or "public/mask_1.png"   -- 遮罩图片
    local clearHei          = element.attr.clearhei                         -- 刮除高度
    local moveTime          = tonumber(element.attr.movetime) or 5          -- 移动时间
    local beginTime         = tonumber(element.attr.begintime)              -- 开始按下时间
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox

    local widget = global.SWidgetCache:generateRender("ccui.Layout")
    widget:setBackGroundColorType(0)
    widget:setTouchEnabled(false)


    local path              = SUIHelper.fixImageFileName(showImg)
    local img               = nil
    local fullPath          = (path and path ~= "") and string.format(getResFullPath("res/%s"), path) or ""
    if not fullPath or fullPath == "" or not global.FileUtilCtl:isFileExist(fullPath) then
        img                 = global.SWidgetCache:generateEmptyImageRender("ccui.ImageView")
    else
        img                 = global.SWidgetCache:generateRender("ccui.ImageView")
    end
   
    img:loadTexture(fullPath)
    img:ignoreContentAdaptWithSize(false)
    img:setContentSize(img:getVirtualRendererSize())
    widget:addChild(img)
    local imgSize = img:getContentSize()
    widget:setContentSize(imgSize)
    img:setAnchorPoint(cc.p(0.5, 0.5))
    img:setPosition(cc.p(fixPosition(imgSize.width / 2), fixPosition(imgSize.height / 2)))

    if imgSize.width == 0 or imgSize.height == 0 then
        return widget
    end

    local radius = clearHei and mfloor(clearHei / 2) or 8
    local drawNode = cc.DrawNode:create()
    widget:addChild(drawNode)
    drawNode:retain()
    drawNode:drawSolidCircle(cc.p(0, 0), radius, 0, radius, 1, 1, cc.c4b(0, 0, 0, 0))
    drawNode:setVisible(false)

    local renderTexture = cc.RenderTexture:create(imgSize.width, imgSize.height)
    widget:addChild(renderTexture, 10)
    renderTexture:retain()
    renderTexture:setPosition(cc.p(fixPosition(imgSize.width / 2), fixPosition(imgSize.height / 2)))

    local mask              = nil
    local path              = SUIHelper.fixImageFileName(maskImg)
    local fullPath          = (path and path ~= "") and string.format(getResFullPath("res/%s"), path)
    if not fullPath or fullPath == "" or not global.FileUtilCtl:isFileExist(fullPath) then
        mask                = global.SWidgetCache:generateEmptyImageRender("ccui.ImageView")
    else
        mask                = global.SWidgetCache:generateRender("ccui.ImageView")
    end
    mask:loadTexture(fullPath)
    mask:ignoreContentAdaptWithSize(false)
    mask:setContentSize(imgSize)
    mask:setAnchorPoint(cc.p(0.5, 0.5))
    mask:setPosition(cc.p(fixPosition(imgSize.width / 2), fixPosition(imgSize.height / 2)))
    renderTexture:begin()
    mask:visit()
    renderTexture:endToLua()


    local lastMovePos = nil
    local moveBT = nil
    local iMoveTime = 0
    local iBeginAct = nil
    local releaseCount = 0
    local touchPosList = {}

    local function timeCB()
        if releaseCount == 0 then
            releaseCount = releaseCount + 1

            if drawNode then
                drawNode:removeFromParent()
                drawNode:autorelease()
                drawNode = nil
            end
            
            if renderTexture then
                renderTexture:removeFromParent()
                renderTexture:autorelease()
                renderTexture = nil
            end

            if callback and link and string.len(link) > 0 then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end
        end
    end

    local function getKey(x, y)
        return x * 10000 + y
    end

    local function addTouchPoint(x, y)
        local key = getKey(x, y)
        if touchPosList[key] then
            return
        end
        if x <= 0 or x >= imgSize.width then
            return
        end
        if y <= 0 or y >= imgSize.height then
            return
        end
        
        if not touchPosList[key] then
            touchPosList[key] = true
        end
    end

    widget:setTouchEnabled(true)
    widget:addTouchEventListener(function (node, eventType)
        if eventType == 0 then
            lastMovePos = nil
            moveBT = os.clock()
            if tonumber(beginTime) and not iBeginAct then
                iBeginAct = performWithDelay(widget, function()
                    timeCB()
                end, tonumber(beginTime))
            end

        elseif eventType == 1 then
            if releaseCount > 0 then
                return
            end

            local movedPos = node:getTouchMovePosition()
            local tt = GUI:convertToNodeSpace(widget, movedPos.x, movedPos.y)
            tt = fixPosition(tt)
            local key = getKey(tt.x, tt.y)
            if touchPosList[key] then
                return
            end
            
            drawNode:setPosition(tt)
            drawNode:setBlendFunc({src = gl.ONE, dst = gl.ZERO})
            drawNode:setVisible(true)
            renderTexture:begin()
            drawNode:visit()
            renderTexture:endToLua()
            drawNode:setVisible(false)

            if lastMovePos then
                local distance = math.abs(cc.pGetDistance(lastMovePos, movedPos))
                local pos = cc.pSub(lastMovePos, movedPos)
                local angle = 180 * (cc.pToAngleSelf(pos) / math.pi)

                local height = radius * 2
                local midPos = cc.pMidpoint(lastMovePos, movedPos)
                midPos = fixPosition(GUI:convertToNodeSpace(widget, midPos.x, midPos.y))
                local rectNode = cc.DrawNode:create()
                local posList = {
                    cc.p(- distance / 2 , - height / 2),
                    cc.p(- distance / 2 , height / 2),
                    cc.p(distance / 2 , height / 2),
                    cc.p(distance / 2 , - height / 2)
                }
                rectNode:drawSolidPoly(posList, 4, cc.c4b(0,0,0,0))
                rectNode:setPosition(midPos)
                rectNode:setRotation(angle)
                rectNode:setBlendFunc({src = gl.ONE, dst = gl.ZERO})
                renderTexture:begin()
                rectNode:visit()
                renderTexture:endToLua()
            end
               
            -- pos
            local mPos = GUI:convertToNodeSpace(widget, movedPos.x, movedPos.y)
            mPos = fixPosition(mPos)
            for i = mPos.x - radius, mPos.x + radius do
                for j = mPos.y - radius, mPos.y + radius do
                    if math.pow(i - mPos.x, 2) + math.pow(j - mPos.y, 2) <= math.pow(radius, 2) then
                        addTouchPoint(i, j)
                    end
                end
            end

            if moveBT then
                iMoveTime = iMoveTime + (os.clock() - moveBT)
            end
            moveBT = os.clock()

            if tonumber(moveTime) then
                if iMoveTime >= tonumber(moveTime) then
                    timeCB()
                end
            end

            lastMovePos = movedPos

        elseif eventType == 2 or eventType == 3 then
            lastMovePos = nil
            moveBT = nil
        end
    end)

    return widget
end

function SUILoader:load_render_BmpText(swidget, callback)
    local element           = swidget.element
    local text              = element.attr.text or ""
    local size              = tonumber(element.attr.size) or defaultFontSize
    local color             = tonumber(element.attr.color) or defaultColorID
    local link              = element.attr.link
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local clickInterval     = (tonumber(element.attr.clickInterval) or 0) * 0.001
    local tips              = element.attr.tips
    local tipsx             = tonumber(element.attr.tipsx) or 0
    local tipsy             = tonumber(element.attr.tipsy) or 0
    local tipWidth          = tonumber(element.attr.tipWidth) or 1136


    text = string.gsub(text, "\\", "\r\n")
    text = string.trim(text)

    local widget = ccui.Text:create()
    GUI:SetBmpTextProperties(widget)

    widget:setBMFontFilePath()
    widget:setFontSize(size)
    widget:setTextColor(GET_COLOR_BYID_C3B(color))
    widget:setString(text)

    if link and string.len(link) > 0 or (tips and string.len(tips) > 0) then
        widget:setTouchEnabled(true)
        widget:addClickEventListener(function()
            DelayTouchEnabled(widget, clickInterval)

            widget:setScale(1 + 0.2)
            local function reback()
                widget:setScale(1)
            end
            performWithDelay(widget, reback, 0.03)
            
            if callback and link then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                callback(jsonData)
            end

            if not global.isWinPlayMode then
                if tips and string.len(tips) > 0 then
                    local offset  = cc.p(tipsx, -tipsy)
                    local anchorPoint = cc.p(0.5, 1)
        
                    tips  = string.gsub(tips, "%^", "\\")
                    SHOW_SUI_DESCTIP( widget ,tips, tipWidth, offset, anchorPoint)
                end
            end

        end)

        -- 下划线
        widget:getVirtualRenderer():enableUnderline()
    end

    self:addMouseOverTips(widget, element)

    return widget
end

function SUILoader:load_render_ButtonKeFu(swidget, callback, closeCB)
    local element           = swidget.element
    local nimg              = element.attr.nimg
    local pimg              = element.attr.pimg
    local mimg              = element.attr.mimg
    local text              = element.attr.text or ""
    local color             = tonumber(element.attr.color) or defaultColorID
    local size              = tonumber(element.attr.size) or defaultFontSize
    local width             = tonumber(element.attr.width)
    local height            = tonumber(element.attr.height)
    local link              = element.attr.o_link or element.attr.link or "&701"   -- 没有配置强制默认打开
    local submitInput       = element.attr.submitInput
    local submitCheckBox    = element.attr.submitCheckBox
    local tips              = element.attr.tips
    local tipsx             = tonumber(element.attr.o_tipsx) or tonumber(element.attr.tipsx) or 0
    local tipsy             = tonumber(element.attr.o_tipsy) or tonumber(element.attr.tipsy) or 0
    local textWidth         = tonumber(element.attr.textwidth)
    local grey              = tonumber(element.attr.grey) or 0
    local clickInterval     = (tonumber(element.attr.clickInterval) or 0) * 0.001
    local outline           = tonumber(element.attr.outline) or defaultOutline
    local outlinecolor      = tonumber(element.attr.outlinecolor) or defaultOutlineC
    local tipWidth          = tonumber(element.attr.tipWidth) or 1136
    local redPointTx        = tonumber(element.attr.effectid) or 0
    local redPointPath      = element.attr.redimg
    local redx              = tonumber(element.attr.redx) or 0
    local redy              = tonumber(element.attr.redy) or 0
    local mainIndex         = element.attr._mainIndex
    local widgetID          = element.attr.id

    text = string.gsub(text, "\\", "\r\n")
    text = string.trim(text)

    local nimg      = SUIHelper.fixImageFileName(nimg)
    local pimg      = SUIHelper.fixImageFileName(pimg)
    local mimg      = SUIHelper.fixImageFileName(mimg)
    local fullPathN = (nimg and string.len(nimg) > 0 and string.format(getResFullPath( "res/%s" ), nimg) or "")
    local fullPathP = (pimg and string.len(pimg) > 0 and string.format(getResFullPath( "res/%s" ), pimg) or "")
    local fullPathM = (mimg and string.len(mimg) > 0 and string.format(getResFullPath( "res/%s" ), mimg) or "")

    local widget    = nil
    local isNormalExist = fullPathN ~= "" and global.FileUtilCtl:isFileExist(fullPathN)
    local isPressExist = fullPathP ~= "" and global.FileUtilCtl:isFileExist(fullPathP)
    local isMouseExist = fullPathM ~= "" and global.FileUtilCtl:isFileExist(fullPathM)
    local Button_Type = 1
    --1-normalAndPress 2-Normal 3-Press 4-nil
    if isNormalExist and isPressExist  then
        Button_Type      = 1
    elseif  isNormalExist then
        Button_Type = 2
    elseif isPressExist then
        Button_Type = 3
    else
        Button_Type = 4
    end
    widget = global.SWidgetCache:generateButtonRender(Button_Type)
    widget:resetNormalRender()
    widget:resetPressedRender()
    widget:setTitleText(text)
    widget:setTitleColor(GET_COLOR_BYID_C3B(color))
    widget:setTitleFontName(defaultFontPath)
    widget:setTitleFontSize(size)
    widget:setTouchEnabled(false)
    widget:getTitleRenderer():setMaxLineWidth(0)
    widget:getTitleRenderer():enableOutline(GET_COLOR_BYID_C3B(outlinecolor), outline)


    if isNormalExist then
        widget:loadTextureNormal(fullPathN)
    end
    if isPressExist then
        widget:loadTexturePressed(fullPathP)
    end

    --
    widget:ignoreContentAdaptWithSize(false)
    widget:setContentSize(widget:getVirtualRendererSize())

    swidget.element.attr.o_link     = element.attr.link
    swidget.element.attr.link       = nil
    swidget.element.attr.bg         = nil

    local redPointWidget = nil
    if redPointTx > 0 then
        -- redPointWidget = self:load_render_Effect(swidget)
        redPointWidget = global.FrameAnimManager:CreateSFXAnim(redPointTx)
        redPointWidget:Play(0, 0, true, 1)
    else
        redPointWidget    = ccui.ImageView:create()
        local fullPath    = (redPointPath and redPointPath ~= "") and string.format(getResFullPath("res/%s"), redPointPath) or ""
        if global.FileUtilCtl:isFileExist(fullPath) then
            redPointWidget:loadTexture(fullPath)
        end
        -- redPointWidget = self:load_render_Img(swidget)
    end


    SL:UnRegisterLUAEvent(LUA_EVENT_MANUAL_SERVICE_MESSAGE_UN_READ, "MABUAL_SERVICE_996_RED__"..(widgetID or ""))
    if redPointWidget then
        redPointWidget:setPosition(redx, redy)
        widget:addChild(redPointWidget)

        -- 监听客服红点
        local ManualService996Proxy = global.Facade:retrieveProxy(global.ProxyTable.ManualService996Proxy)
        local unReadNums            = tonumber(ManualService996Proxy:GetUnReadNums()) or 0
        redPointWidget:setVisible(unReadNums > 0)

        SL:RegisterLUAEvent(LUA_EVENT_MANUAL_SERVICE_MESSAGE_UN_READ, "MABUAL_SERVICE_996_RED__"..(widgetID or ""), function(data)
            if not redPointWidget or tolua.isnull(redPointWidget) then
                SL:UnRegisterLUAEvent(LUA_EVENT_MANUAL_SERVICE_MESSAGE_UN_READ, "MABUAL_SERVICE_996_RED__"..(widgetID or ""))
                return
            end
            local unReadNums = data and tonumber(data.unReadNums) or 0
            redPointWidget:setVisible(unReadNums > 0)
        end)
    end

    local showTips      = tips and string.len(tips) > 0
    if isNormalExist and (isMouseExist or showTips) then
        if global.isWinPlayMode then
            local function checkResType(path)
                if global.SpriteFrameCache:getSpriteFrame(path) then
                    return 1
                end
                if global.FileUtilCtl:isFileExist(path) then
                    return 0
                end
                return 0
            end
            local function checkRes(path)
                local resType = checkResType(path)
                if isMouseExist and isNormalExist then
                    widget:loadTextureNormal(path, resType)
                end
            end

            local offset        = cc.p(tipsx, -tipsy)
            local anchor        = cc.p(0.5, 1)
            local function enterCB(touchPos)
                if global.userInputController:isTouching() or not widget:isVisible() then
                    return false
                end
                if not CheckNodeCanCallBack(widget, touchPos) then
                    return false
                end
                checkRes(fullPathM)
                if showTips then
                    tips        = string.gsub(tips, "%^", "\\")
                    showMouseOverTips(widget, tips, offset, anchor)
                end
            end
            local function leaveCB()
                checkRes(fullPathN)
                hideMouseOverTips()
            end
            -- widget:loadTextureMouseOver(fullPathN, fullPathM, enterCB, leaveCB)
            global.mouseEventController:registerMouseMoveEvent(
                widget,
                {
                    enter = enterCB,
                    leave = leaveCB,
                    checkIsVisible = true
                }
            )
        
        end
    end

    -- 加入元变量组件管理
    local isMateValue = false
    local metaValue = {}
    local content = text
    while content and string.len(content) > 0 do
        local find_info = {sfind(content, "$STM%((.-)%)")}
        local begin_pos = find_info[1]
        local end_pos   = find_info[2]

        if begin_pos and end_pos then
            isMateValue = true

            -- prefix
            if begin_pos ~= 1 then
                local substr = string.sub(content, 1, begin_pos - 1)
                table.insert(metaValue, substr)
            end

            -- metaValue
            local slices = ssplit(find_info[3], "_")
            table.insert(metaValue, {key = slices[1], param = slices[2]})

            -- suffix
            content = string.sub(content, end_pos+1, string.len(content))
        else
            table.insert(metaValue, content)
            content = ""
        end
    end
    if isMateValue then
        widget.useMetaValue = true
        global.Facade:sendNotification(global.NoticeTable.SUIMetaWidgetAdd, {metaValue = metaValue, widget = widget, lifewidget = widget})
    end

    if textWidth then
        local renderer = widget:getTitleRenderer()
        renderer:setMaxLineWidth(textWidth)
    end
   
    -- link
    if link and string.len(link) > 0 or (tips and string.len(tips) > 0) then
        widget:setTouchEnabled(true)
        widget:addClickEventListener(function()
            DelayTouchEnabled(widget, clickInterval)

            if mainIndex then
                -- 数据上报
                local NativeBridgeProxy = global.Facade:retrieveProxy(global.ProxyTable.NativeBridgeProxy)
                NativeBridgeProxy:GN_MainUIClickEvent({
                    index = mainIndex,
                    id = element.attr.id,
                    link = link
                })
            end

            if link == "@DEFAULT_CLOSE" then
                if closeCB then
                    closeCB()
                end

            elseif callback and link then
                local inputTable    = self:getInputTable(submitInput)
                local checkBoxTable = self:getCheckBoxTable(submitCheckBox)
                local jsonData      = {}
                jsonData.Act        = link
                jsonData.Input      = (#inputTable > 0 and inputTable or nil)
                jsonData.CheckBox   = (#checkBoxTable > 0 and checkBoxTable or nil)
                self:linkFuncWithCheckWords(callback, jsonData)
            end

            if not global.isWinPlayMode then
                if tips and string.len(tips) > 0 then
                    local offset  = cc.p(tipsx, -tipsy)
                    local anchorPoint = cc.p(0.5, 1)
            
                    tips  = string.gsub(tips, "%^", "\\")
                    SHOW_SUI_DESCTIP( widget ,tips, tipWidth, offset, anchorPoint)
                end
            end

        end)
    end

    -- if nil == mimg then
    --     self:addMouseOverTips(widget, element)
    -- end

    -- grey
    if grey == 1 then
        Shader_Grey(widget)
    else
        Shader_Normal(widget)
    end

    return widget
end

return SUILoader

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则