UI Text

From GiderosMobile
Revision as of 13:32, 8 December 2019 by MoKaLux (talk | contribs)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.


Here you will find various resources to help you create texts in Gideros Studio.


note:You may have to provide your own assets (fonts, gfx, …).

Text Wrap @Gideros Wiki

-- TEXT WRAP FROM GIDEROS WIKI
local mystring = "Some very long text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor."
local textfield = TextField.new(nil, mystring)
textfield:setScale(2)
textfield:setSample(mystring)
textfield:setLayout( {w=144, h=100, lineSpacing=7, flags=FontBase.TLF_CENTER} )
textfield:setPosition(8, 16)
stage:addChild(textfield)

TextBox @antix

Textbox.png

-- @antix
TextBox = Core.class(Sprite)

function TextBox:init(options)
	-- default options
	local props = {
		x	= 0,
		y	= 0,
		width = 256, -- constrain width of TextBox to this
		linePadding = 3, -- pixel gap between text lines
		color = 0xe0e0e0, -- default text color
		font = Font:getDefault(),
		text = "",
	}

	-- overwrite default options
	if options then
		for key, value in pairs(options) do
			props[key]= value
		end
	end
	self.props = props

	-- we only need one actual TextField that we will reuse to render our TextBox
	local brush = TextField.new(props.font, "")
	self.brush = brush
	self:redraw()
end

-- set new text and redraw
function TextBox:setText(text)
	local props = self.props
	props.text = text
	self:redraw()
end

-- set new font and redraw
function TextBox:setFont(font)
	local props = self.props
	props.font = font
	self:redraw()
end

-- redraw the textbox
function TextBox:redraw()
	local props = self.props
	local font = props.font

	-- discard any previous imagery
	if self:getNumChildren() > 0 then
		self:removeChildAt(1)
	end

	-- calculate various offsets
	local lineHeight = font:getLineHeight()
	local actualHeight = lineHeight + props.linePadding
	self.lineHeight = lineHeight
	self.actualHeight = actualHeight

	-- split and format text
	local lines = self:splitText(props.text, font, props.width)
	self.lines = lines

	-- create a blank canvas where we will render our text
	local canvas = RenderTarget.new(props.width, (#lines + 1) * actualHeight)
	self.canvas = canvas

	local brush = self.brush
	-- render text to canvas
	for i = 1, #lines do
		local line = lines[i]
		local words = line.words
		for w = 1, #words do
			local word = words[w]
			brush:setText(word.word)
			brush:setTextColor(word.color)
			brush:setPosition(word.x + line.x, i * actualHeight)
			canvas:draw(brush)
			--print(string.format("word=%s, x=%d, 0x%06x", word.word, word.x, word.color))
		end
	end

	-- create bitmap to display
	local bitmap = Bitmap.new(canvas) -- our canvas is the texture)
	bitmap:setPosition(props.x, props.y)

	self:addChild(bitmap)
end

-- recolor a single matching string text or all matching text if "all = true"
function TextBox:recolor(text, color, all)
	local brush = self.brush
	local canvas = self.canvas

	local lineHeight = self.lineHeight
	local actualHeight = self.actualHeight

	local lines = self.lines
	for i = 1, #lines do
		local line = lines[i]
		local words = line.words
		for j = 1, #words do
			local word = words[j]
			if word.word == text then
				canvas:clear(0x000000, 0, word.x + line.x, i * actualHeight - lineHeight, word.width, actualHeight) -- clear area where word was
				word.color = color
				brush:setText(word.word)
				brush:setTextColor(color)
				brush:setPosition(word.x + line.x, i * actualHeight)
				canvas:draw(brush) -- draw word
				if not all then
					return
				end
			end
		end
	end
end

-- this does the heavy lifting, splitting and formatting text lines and words
function TextBox:splitText(text, font, maxWidth)
	local props = self.props

	local spaceWidth = font:getAdvanceX(" ")

	local words = {}
	local lines = {}
	local wordList = {}

	-- split text into words (space separated)
	local smatch = string.gmatch
	local pattern = '([^ ]+)'
	for str in smatch(text, pattern) do
		words[#words + 1] = str
	end

	local i = 1 -- which word we are currently processing
	local x = 0 -- the x offset for any line of text
	local lineWidth = 0 -- total width of text in pixels
	local color = props.color -- initial color
	local align = "left" -- current alignment
	local line = ""

	local function newLine()
		-- calculate offset for aligned text
		if align == "left" then
			x = 0
		elseif align == "right" then
			x = maxWidth - lineWidth
		elseif align == "center" then
			x = (maxWidth * 0.5) - (lineWidth * 0.5)
		end
		
		lines[#lines + 1] = {
			color = color,
			text = line,
			align = align,
			width = font:getAdvanceX(line),
			words = wordList,
			x = x,
		}

		lineWidth = 0
		line = ""
		wordList = {}
		i = i + 1
	end

	local done = false
	repeat
		local word = words[i]

		if word == "#n#" then
			-- process line feed
			newLine()
		elseif word == "#color#" then
			-- process text color change
			color = tonumber(words[i + 1])
			i = i + 2
		elseif word == "#align#" then
			-- process text alignment
			align = words[i + 1]
			i = i + 2
		else
			-- process a normal word
			local wordWidth = font:getAdvanceX(word)

			local w = {
				word = word,
				width = wordWidth,
				x = lineWidth,
				color = color,
			}

			if lineWidth + wordWidth + spaceWidth >= maxWidth then
				-- container width exceeded, create a new line but skip back one word because it needs to appear on the next line
				i = i - 1
				newLine()
			else
				-- process word normally
				wordList[#wordList + 1] = w
				line = line .. " " .. word
				lineWidth = lineWidth + wordWidth + spaceWidth
				i = i + 1
			end
		end

		if i > #words then
			-- all words processed, append the last line and set exit condition
			newLine()
			done = true
		end
	until done

	return lines
end

--[[
-- USAGE
local textBox = TextBox.new(
	{
	  text = "This is a TextBox. It contains text that is automatically split into multiple lines"..
		" and of course every #color# 0x0066ff word #color# 0x33ff55 can #color# 0x33ffff be"..
		" #color# 0xff66ff individually #color# 0x00ff00 colored."..
		" #color# 0xffffff Then there are line breaks which make life..."..
		" #n# #n# so much easier!!!"..
		" #n# #n# #color# 0xf00000 #align# right Lets align the text to the right #n#"..
		" It looks pretty good this way #n# #n# #align# center #color# 0x4080d0 but centered text #n# is always good"..
		" also #n# #n# #color# 0xf0f0f0 #align# left Well that's a wrap :)",
	}
)
stage:addChild(textBox)
-- recolor all occurences of "is" to the color magenta
textBox:recolor("is", 0xff00ff, true)
-- recolor the first occurence of "the" to the color cyan
textBox:recolor("the", 0x00ffff)
]]

Typewriter Style @koeosstudio

-- @koeosstudio
console = Core.class(Sprite)

function console:init()
	local fnt = TTFont.new("Assets/arial.ttf", 20)
	self.txt = TextField.new(fnt, nil)
	self.txt:setLayout({w = 300, flags=FontBase.TLF_LEFT})
	self.txt:setAnchorPoint(0, 0)
	self:addChild(self.txt)
	self.allowType = true

	-- Simple scroll function
	local z = nil
	self:addEventListener(Event.MOUSE_DOWN, function (event)
		z = event.y - self.txt:getY()
	end)
	self:addEventListener(Event.MOUSE_MOVE, function (event)
		self.txt:setY(event.y - z)
	end)
end

function console:tWrite(txtToPrint)
	if self.allowType then
		self.allowType = false
		local i = 1
		self.txt:setText(self.txt:getText()..'\n')

		local function typeFunc()
			self.txt:setText(self.txt:getText()..string.sub(txtToPrint, i, i))
			i = i + 1
			
			if i > string.len(txtToPrint) then
				self.allowType = true
				self:removeEventListener(Event.ENTER_FRAME, typeFunc)
			end
		end

		self:addEventListener(Event.ENTER_FRAME, typeFunc)
	end
end

-- Usage
application:setLogicalDimensions(480, 800)
local myconsole = console.new()
stage:addChild(myconsole)
-- Generate sample txt 
local s = ""
for i = 1, 10 do
	s = s.."TextField with typewriter effect. Drag to Scroll.\n\n"
end
-- Print
myconsole:tWrite(s)