-- Author: zlf
-- Date: 2016年5月9日17:05:37
-- 简易富文本
RichText = class("RichText", function()
return ccui.Layout:create()
end)
--自适应最大宽度,自动换行
RichText.auto = 1
--系统公告,无限宽
RichText.gmnotice = 2
local cache = cc.SpriteFrameCache:getInstance()
--[[
@param data 富文本参数(table)
data示例:{{txt="12呵呵asdasad###3", color="#FF9966", isUnLine = 1, data = "函数回调参数"}, {img = "Star.png", data = "函数回调参数"}}
使用方式:
local richLabel = RichText:create()
setDrawType可用可不用,但是create之后一定要手动调用init函数
richLabel:setDrawType(1)
richLabel:init(param, 300)
richLabel:setPosition(300, 320)
self:addChild(richLabel)
data里面元素作用详解:
txt代表要创建的控件是ccui.Text,img则代表ccui.ImageView, color设置ccui.Text的字体颜色
isUnLine用来表示ccui.Text是否需要下划线,nil或者false代表不画, data作为控件回调函数的参数
fontSize用来设置ccui.Text的字体大小
@param maxWidth 富文本的最大宽度,设置了最大宽度,可以自动换行
@param globalCallBack 全局回调函数,当这个参数存在时,所有的控件回调都调用这个函数
@param globalFontSize 全局字体大小,当这个参数存在时,所有的ccui.Text的字体大小都设置为这个参数
@param this 类指针,callback(this, callParam)这个作用,语法糖
]]
function RichText:create()
local ret = RichText.new()
return ret
end
--2016年6月12日19:53:03 去掉了几个全局参数 callback字段也不用了
-- function RichText:init(param, maxWidth, globalCallBack, globalColor, globalFontSize, this)
function RichText:init(param, maxWidth, globalCallBack, this)
if type(param) ~= "table" then
return
end
self:removeAllChildren()
self.globalCallBack = globalCallBack
self.globalFontSize = globalFontSize
self.renderWidth = 0
self.renderLine = 0
maxWidth = maxWidth or 400
local curWidth = 0
local row = 0
local curIndex = 1
local allWidget = {}
for i=1,#param do
local x, y = 0
if param[i].txt and param[i].txt ~= "" then
local textTb = Utils.separate(param[i].txt)
for j=1,#textTb do
local color = self:getNeedColor(globalColor, param[i].color)
local widget = self:getLabel(textTb[j], color, globalCallBack, param[i].data, globalFontSize or param[i].fontSize, this)
widget.isUnLine = param[i].isUnLine
local size = widget:getContentSize()
x, y = curWidth, size.height * row
local width = size.width
if curWidth + width > maxWidth then
curWidth = width
row = row - 1
curIndex = curIndex + 1
x, y = 0, size.height * row
else
curWidth = curWidth + width
end
if not allWidget[curIndex] then
allWidget[curIndex] = {}
end
table.insert(allWidget[curIndex], widget)
widget:setPosition(x, y)
widget:setAnchorPoint(cc.p(0, 0.5))
widget.trueRow = curIndex
self:addChild(widget)
end
elseif param[i].img then
local widget = self:getImage(param[i].img, globalCallBack, globalParam or param[i].data, this)
local size = widget:getContentSize()
x, y = curWidth, size.height * row
if curWidth + size.width > maxWidth then
curWidth = size.width
row = row - 1
curIndex = curIndex + 1
x, y = 0, size.height * row
else
curWidth = curWidth + size.width
end
if not allWidget[curIndex] then
allWidget[curIndex] = {}
end
table.insert(allWidget[curIndex], widget)
widget:setAnchorPoint(cc.p(0, 0.5))
widget:setPosition(x, y)
self:addChild(widget)
elseif param[i].anim then
end
end
self.renderWidth = curIndex > 1 and maxWidth or curWidth
self.renderLine = curIndex
self:adjust(allWidget)
end
function RichText:setDrawType(type)
self.DrawType = type
end
function RichText:setRowSpace(space)
self.rowSpace = space
end
function RichText:adjust(allWidget)
self.DrawType = self.DrawType or self.auto
self.renderHeight = 0
if self.DrawType == self.auto then
self.rowSpace = self.rowSpace or 0
local _max = {}
for i=1,#allWidget do
local maxHeight = 0
for k,v in pairs(allWidget[i]) do
local size
if v.isAnim then
size = v.size
else
size = v:getContentSize()
end
if size.height * 0.5 > maxHeight then
maxHeight = size.height * 0.5 + self.rowSpace
end
end
self.renderHeight = self.renderHeight + maxHeight
if i == 1 then
self.posX = maxHeight - self.rowSpace
end
if maxHeight > 0 then
if _max[i-1] then
_max[i] = maxHeight*2 + _max[i-1]
else
_max[i] = maxHeight
end
for k,v in pairs(allWidget[i]) do
local height = 0
if _max[i-1] then
height = -maxHeight - _max[i-1]
else
height = 0
end
v:setPositionY(height)
if v.isUnLine then
self:drawUnLine(self, v)
end
end
end
end
self:setContentSize(cc.size(self.renderWidth, self.renderHeight))
else
local all = {}
local allWidth = {}
local maxHeight = -100
for k,v in pairs(allWidget) do
for key,value in pairs(v) do
local size
if value.isAnim then
size = value.size
else
size = value:getContentSize()
end
if size.height * 0.5 > maxHeight then
maxHeight = size.height * 0.5
end
table.insert(all, value)
table.insert(allWidth, value:getContentSize().width)
end
if k == 1 then
self.posX = maxHeight
end
end
self.renderHeight = maxHeight
local curWidth = 0
for i=1,#all do
all[i]:setPosition(curWidth, 0)
curWidth = curWidth + allWidth[i]
self.renderWidth = curWidth
if all[i].isUnLine then
self:drawUnLine(self, all[i])
end
end
self.renderLine = 1
end
self:setContentSize(cc.size(self.renderWidth, 0))
end
function RichText:getRenderWidth()
return self.renderWidth
end
function RichText:getRenderLine()
return self.renderLine
end
function RichText:getRenderHeight()
return self.renderHeight
end
function RichText:drawUnLine(parent, widget)
local color4F = cc.convertColor(widget:getColor(), "4f")
color4F.a = 1
local pos = cc.p(widget:getPosition())
self:getDrawNode(parent):drawLine(cc.p(pos.x, pos.y - widget:getContentSize().height/2), cc.p(pos.x + widget:getContentSize().width, pos.y - widget:getContentSize().height/2), color4F)
end
function RichText:getDrawNode(parent)
if not self.drawNode then
self.drawNode = cc.DrawNode:create()
parent:addChild(self.drawNode)
end
return self.drawNode
end
function RichText:getLabel(param, color, callback, funcParam, fontSize, this)
local text = ccui.Text:create()
text:setFontName("Arial")
text:setFontSize(fontSize or 22)
text:setString(param)
if color then
text:setColor(color)
end
if funcParam then
text:setTouchEnabled(true)
if type(callback) == "function" then
text:addTouchEventListener(function(sender, event)
if event == ccui.TouchEventType.ended then
if this then
callback(this, funcParam)
else
callback(funcParam)
end
end
end)
end
end
text:enableShadow(cc.c4b(0,0,0,255), cc.size(1,-1))
return text
end
function RichText:getImage(param, callback, callParam, this)
local img = ccui.ImageView:create()
if not cache:getSpriteFrame(param) then
img:loadTexture(param)
else
img:loadTexture(param, ccui.TextureResType.plistType)
end
if callParam then
img:setTouchEnabled(true)
if type(callback) == "function" then
img:addTouchEventListener(function(sender, event)
if event == ccui.TouchEventType.ended then
if this then
callback(this, callParam)
else
callback(callParam)
end
end
end)
end
end
return img
end
function RichText:getNeedColor(p1, p2)
local result
if p1 then
result = p1
elseif p2 then
result = p2
else
result = cc.c3b(255,255,255)
end
if type(result) == "string" then
result = Utils.str2Color(result)
end
return result
end
function RichText:setPos(x, y)
self.posX = self.posX or 0
if type(x) == "table" then
x.y = x.y - self.posX
self:setPosition(x)
else
y = y - self.posX
self:setPosition(x, y)
end
end