Löve Frames - A GUI Library

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
megalukes
Citizen
Posts: 93
Joined: Fri Jun 27, 2014 11:29 pm
Location: Brazil

Re: Löve Frames - A GUI Library

Post by megalukes » Tue Sep 16, 2014 2:05 pm

Hi again. I just got a strange error here. In the text input GUI when I try to use a special character (as ~ãõéëãâ, stuff like you'd use in latin languages like portuguese and spanish) it returns the following error:

Code: Select all

Error: loveframes/objects/textinput.lua:924: Decoding error: Not enough space
stack traceback:
	[C]: in function 'getWidth'
	loveframes/objects/textinput.lua:924: in function 'UpdateIndicator'
	loveframes/objects/textinput.lua:873: in function 'MoveIndicator'
	loveframes/objects/textinput.lua:810: in function 'RunKey'
	loveframes/objects/textinput.lua:538: in function 'textinput'
	loveframes/objects/base.lua:256: in function 'textinput'
	loveframes/objects/base.lua:256: in function 'textinput'
	loveframes/init.lua:306: in function 'textinput'
	main.lua:145: in function <main.lua:141>
	[string "boot.lua"]:425: in function <[string "boot.lua"]:399>
	[C]: in function 'xpcall'
[Finished in 14.2s with exit code 1]

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Löve Frames - A GUI Library

Post by Robin » Tue Sep 16, 2014 5:11 pm

Could you please upload a .love?
Help us help you: attach a .love.

User avatar
megalukes
Citizen
Posts: 93
Joined: Fri Jun 27, 2014 11:29 pm
Location: Brazil

Re: Löve Frames - A GUI Library

Post by megalukes » Tue Sep 16, 2014 5:20 pm

Robin wrote:Could you please upload a .love?
Sure. Here it is.

I added this in case you don't have special characters in your keyboard:

Code: Select all

textinput:SetText("Não está, âncora, corações")
If I take those special characters off it works perfectly.
Attachments
loveframes error.love
(178.28 KiB) Downloaded 68 times

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Löve Frames - A GUI Library

Post by Robin » Tue Sep 16, 2014 5:43 pm

Ah, I see. It is a bug in Löve Frames: it doesn't support anything that's not ASCII.
Help us help you: attach a .love.

User avatar
megalukes
Citizen
Posts: 93
Joined: Fri Jun 27, 2014 11:29 pm
Location: Brazil

Re: Löve Frames - A GUI Library

Post by megalukes » Tue Sep 16, 2014 5:44 pm

Robin wrote:Ah, I see. It is a bug in Löve Frames: it doesn't support anything that's not ASCII.
So there's no way to fix this? D:

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Löve Frames - A GUI Library

Post by Robin » Tue Sep 16, 2014 5:52 pm

Well, yes. I don't know if Nikolai Resokav still maintains this, but it should be their job to make Löve Frames support UTF-8.

It's open source, so you or someone else inclined to fix it can do so.
Help us help you: attach a .love.

User avatar
megalukes
Citizen
Posts: 93
Joined: Fri Jun 27, 2014 11:29 pm
Location: Brazil

Re: Löve Frames - A GUI Library

Post by megalukes » Tue Sep 16, 2014 7:17 pm

So, I made some snippets here and it works now. Thanks to Kyle Smith's utf8.lua I replaced all those string:sub lines for string.utf8sub in loveframes/objects/textinput.lua.

Here's the code if someone is going through the same. Thanks!

Code: Select all

--[[------------------------------------------------
	-- Love Frames - A GUI library for LOVE --
	-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------

require("utf8")
local utf8 = {}
utf8.sub2 = string.utf8sub 


-- textinput object
local newobject = loveframes.NewObject("textinput", "loveframes_object_textinput", true)

--[[---------------------------------------------------------
	- func: initialize()
	- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
	
	self.type = "textinput"
	self.keydown = "none"
	self.tabreplacement = "        "
	self.maskchar = "*"
	self.font = loveframes.basicfont
	self.width = 200
	self.height = 25
	self.delay = 0
	self.repeatdelay = 0.80
	self.repeatrate = 0.02
	self.offsetx = 0
	self.offsety = 0
	self.indincatortime = 0
	self.indicatornum = 0
	self.indicatorx = 0
	self.indicatory = 0
	self.textx = 0
	self.texty = 0
	self.textoffsetx = 5
	self.textoffsety = 5
	self.unicode = 0
	self.limit = 0
	self.line = 1
	self.itemwidth = 0
	self.itemheight = 0
	self.extrawidth = 0
	self.extraheight = 0
	self.rightpadding = 0
	self.bottompadding = 0
	self.lastclicktime = 0
	self.maxx = 0
	self.buttonscrollamount = 0.10
	self.mousewheelscrollamount = 5
	self.usable = {}
	self.unusable = {}
	self.lines = {""}
	self.placeholder = ""
	self.internals = {}
	self.showindicator = true
	self.focus = false
	self.multiline = false
	self.vbar = false
	self.hbar = false
	self.alltextselected = false
	self.linenumbers = true
	self.linenumberspanel = false
	self.editable = true
	self.internal = false
	self.autoscroll = false
	self.masked = false
	self.OnEnter = nil
	self.OnTextChanged = nil
	self.OnFocusGained = nil
	self.OnFocusLost = nil
	self.OnCopy = nil
	self.OnPaste = nil
	
end

--[[---------------------------------------------------------
	- func: update(deltatime)
	- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)

	local state = loveframes.state
	local selfstate = self.state
	
	if state ~= selfstate then
		return
	end
	
	local visible = self.visible
	local alwaysupdate = self.alwaysupdate
	
	if not visible then
		if not alwaysupdate then
			return
		end
	end
	
	-- check to see if the object is being hovered over
	self:CheckHover()
	
	local time = love.timer.getTime()
	local keydown = self.keydown
	local parent = self.parent
	local base = loveframes.base
	local update = self.Update
	local font = self.font
	local theight = font:getHeight()
	local delay = self.delay
	local lines = self.lines
	local numlines = #lines
	local multiline = self.multiline
	local width = self.width
	local height = self.height
	local vbar = self.vbar
	local hbar = self.hbar
	local inputobject = loveframes.inputobject
	local internals = self.internals
	local repeatrate = self.repeatrate
	local hover = self.hover
	
	-- move to parent if there is a parent
	if parent ~= base then
		local parentx = parent.x
		local parenty = parent.y
		local staticx = self.staticx
		local staticy = self.staticy
		self.x = parentx + staticx
		self.y = parenty + staticy
	end
	
	if inputobject ~= self then
		self.focus = false
		self.alltextselected = false
	end
	
	self:PositionText()
	self:UpdateIndicator()
	
	-- calculations for multiline mode
	if multiline then
		local twidth = 0
		local panel = self:GetLineNumbersPanel()
		local textoffsetx = self.textoffsetx
		local textoffsety = self.textoffsety
		local linenumbers = self.linenumbers
		local masked = self.masked
		local maskchar = self.maskchar
		-- get the longest line of text
		for k, v in ipairs(lines) do
			local linewidth = 0
			if masked then
				linewidth = font:getWidth(v:gsub(".", maskchar))
			else
				linewidth = font:getWidth(v)
			end
			if linewidth > twidth then
				twidth = linewidth
			end
		end
		-- item width calculation
		if vbar then
			self.itemwidth = twidth + 16 + textoffsetx * 2
		else
			self.itemwidth = twidth
		end
		if panel then
			local panelwidth = panel.width
			self.itemwidth = self.itemwidth + panelwidth + textoffsetx + 5
		end
		-- item height calculation
		if hbar then
			self.itemheight = theight * numlines + 16 + textoffsety * 2
		else
			self.itemheight = theight * numlines
		end
		-- extra width and height calculations
		self.extrawidth = self.itemwidth - width
		self.extraheight = self.itemheight - height
		local itemwidth = self.itemwidth
		local itemheight = self.itemheight
		if itemheight > height then
			if not vbar then
				local scrollbody = loveframes.objects["scrollbody"]:new(self, "vertical")
				scrollbody.internals[1].internals[1].autoscroll = self.autoscroll
				table.insert(self.internals, scrollbody)
				self.vbar = true
				if hbar then
					local vbody = self:GetVerticalScrollBody()
					local vbodyheight = vbody:GetHeight() - 15
					local hbody = self:GetHorizontalScrollBody()
					local hbodywidth = hbody:GetWidth() - 15
					vbody:SetHeight(vbodyheight)
					hbody:SetWidth(hbodywidth)
				end
			end
		else
			if vbar then
				self:GetVerticalScrollBody():Remove()
				self.vbar = false
				self.offsety = 0
				if self.hbar then
					local hbody = self:GetHorizontalScrollBody()
					local hbodywidth = hbody:GetWidth() - 15
					hbody:SetWidth(hbodywidth)
				end
			end
		end
		
		if itemwidth > width then
			if not hbar then
				local scrollbody = loveframes.objects["scrollbody"]:new(self, "horizontal")
				scrollbody.internals[1].internals[1].autoscroll = self.autoscroll
				table.insert(self.internals, scrollbody)
				self.hbar = true
				if self.vbar then
					local vbody = self:GetVerticalScrollBody()
					local hbody = self:GetHorizontalScrollBody()
					vbody:SetHeight(vbody:GetHeight() - 15)
					hbody:SetWidth(hbody:GetWidth() - 15)
				end
			end
		else
			if hbar then
				self:GetHorizontalScrollBody():Remove()
				self.hbar = false
				self.offsetx = 0
				if vbar then
					local vbody = self:GetVerticalScrollBody()
					if vbody then
						vbody:SetHeight(vbody:GetHeight() + 15)
					end
				end
			end
		end
		if linenumbers then
			if not self.linenumberspanel then
				local linenumberspanel = loveframes.objects["linenumberspanel"]:new(self)
				table.insert(internals, linenumberspanel)
				self.linenumberspanel = true
			end
		else
			if self.linenumberspanel then
				table.remove(internals, 1)
				self.linenumberspanel = false
			end
		end
	end
	
	for k, v in ipairs(internals) do
		v:update(dt)
	end
	
	if update then
		update(self, dt)
	end
	
end

--[[---------------------------------------------------------
	- func: draw()
	- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()

	local state = loveframes.state
	local selfstate = self.state
	
	if state ~= selfstate then
		return
	end
	
	local visible = self.visible
	if not visible then
		return
	end
	
	local x = self.x
	local y = self.y
	local width = self.width
	local height = self.height
	local skins = loveframes.skins.available
	local skinindex = loveframes.config["ACTIVESKIN"]
	local defaultskin = loveframes.config["DEFAULTSKIN"]
	local stencilfunc = function() love.graphics.rectangle("fill", x, y, width, height) end
	local selfskin = self.skin
	local skin = skins[selfskin] or skins[skinindex]
	local drawfunc = skin.DrawTextInput or skins[defaultskin].DrawTextInput
	local drawoverfunc = skin.DrawOverTextInput or skins[defaultskin].DrawOverTextInput
	local draw = self.Draw
	local drawcount = loveframes.drawcount
	local internals = self.internals
	local vbar = self.vbar
	local hbar = self.hbar
	
	-- set the object's draw order
	self:SetDrawOrder()
	
	if vbar and hbar then
		stencilfunc = function() love.graphics.rectangle("fill", x, y, width - 16, height - 16) end
	end
	
	love.graphics.setStencil(stencilfunc)
	
	if draw then
		draw(self)
	else
		drawfunc(self)
	end
	
	love.graphics.setStencil()
	
	for k, v in ipairs(internals) do
		v:draw()
	end
	
	if not draw then
		drawoverfunc(self)
	end

end

--[[---------------------------------------------------------
	- func: mousepressed(x, y, button)
	- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)

	local state = loveframes.state
	local selfstate = self.state
	
	if state ~= selfstate then
		return
	end
	
	local visible = self.visible
	if not visible then
		return
	end
	
	local hover = self.hover
	local internals = self.internals
	local vbar = self.vbar
	local hbar = self.hbar
	local scrollamount = self.mousewheelscrollamount
	local focus = self.focus
	local alltextselected = self.alltextselected
	local onfocusgained = self.OnFocusGained
	local onfocuslost = self.OnFocusLost
	local time = love.timer.getTime()
	local inputobject = loveframes.inputobject
	
	if hover then
		if button == "l" then
			if inputobject ~= self then
				loveframes.inputobject = self
			end
			if not alltextselected then
				local lastclicktime = self.lastclicktime
				if (time > lastclicktime) and time < (lastclicktime + 0.25) then
					if not self.multiline then
						if self.lines[1] ~= "" then
							self.alltextselected = true
						end
					else
						self.alltextselected = true
					end
				end
			else
				self.alltextselected = false
			end
			self.focus = true
			self.lastclicktime = time
			self:GetTextCollisions(x, y)
			if onfocusgained and not focus then
				onfocusgained(self)
			end
			local baseparent = self:GetBaseParent()
			if baseparent and baseparent.type == "frame" then
				baseparent:MakeTop()
			end
		elseif button == "wu" then
			if vbar and not hbar then
				local vbar = self:GetVerticalScrollBody().internals[1].internals[1]
				vbar:Scroll(-scrollamount)
			elseif vbar and hbar then
				local vbar = self:GetVerticalScrollBody().internals[1].internals[1]
				vbar:Scroll(-scrollamount)
			elseif not vbar and hbar then
				local hbar = self:GetHorizontalScrollBody().internals[1].internals[1]
				hbar:Scroll(-scrollamount)
			end
		elseif button == "wd" then
			if vbar and not hbar then
				local vbar = self:GetVerticalScrollBody().internals[1].internals[1]
				vbar:Scroll(scrollamount)
			elseif vbar and hbar then
				local vbar = self:GetVerticalScrollBody().internals[1].internals[1]
				vbar:Scroll(scrollamount)
			elseif not vbar and hbar then
				local hbar = self:GetHorizontalScrollBody().internals[1].internals[1]
				hbar:Scroll(scrollamount)
			end
		end
	else
		if inputobject == self then
			loveframes.inputobject = false
			if onfocuslost then
				onfocuslost(self)
			end
		end
	end
	
	for k, v in ipairs(internals) do
		v:mousepressed(x, y, button)
	end
	
end

--[[---------------------------------------------------------
	- func: mousereleased(x, y, button)
	- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)

	local state = loveframes.state
	local selfstate = self.state
	
	if state ~= selfstate then
		return
	end
	
	local visible = self.visible
	if not visible then
		return
	end
	
	local internals = self.internals
	for k, v in ipairs(internals) do
		v:mousereleased(x, y, button)
	end
	
end

--[[---------------------------------------------------------
	- func: keypressed(key, isrepeat)
	- desc: called when the player presses a key
--]]---------------------------------------------------------
function newobject:keypressed(key, isrepeat)

	local state = loveframes.state
	local selfstate = self.state
	
	if state ~= selfstate then
		return
	end
	
	local visible = self.visible
	
	if not visible then
		return
	end
	
	local time = love.timer.getTime()
	local focus = self.focus
	local repeatdelay = self.repeatdelay
	local alltextselected = self.alltextselected
	local editable = self.editable
	
	self.delay = time + repeatdelay
	self.keydown = key
	
	if (loveframes.util.IsCtrlDown()) and focus then
		if key == "a" then
			if not self.multiline then
				if self.lines[1] ~= "" then
					self.alltextselected = true
				end
			else
				self.alltextselected = true
			end
		elseif key == "c" and alltextselected then
			local text = self:GetText()
			local oncopy = self.OnCopy
			love.system.setClipboardText(text)
			if oncopy then
				oncopy(self, text)
			end
		elseif key == "x" and alltextselected and editable then
			local text = self:GetText()
			local oncut = self.OnCut
			love.system.setClipboardText(text)
			if oncut then
				oncut(self, text)
			else
				self:SetText("")
			end
		elseif key == "v" and editable then
			self:Paste()
		else
			self:RunKey(key, false)
		end
	else
		self:RunKey(key, false)
	end
	
end

--[[---------------------------------------------------------
	- func: keyreleased(key)
	- desc: called when the player releases a key
--]]---------------------------------------------------------
function newobject:keyreleased(key)
	
	local state = loveframes.state
	local selfstate = self.state
	
	if state ~= selfstate then
		return
	end
	
	local visible = self.visible
	if not visible then
		return
	end
	
	self.keydown = "none"
	
end

--[[---------------------------------------------------------
	- func: textinput(text)
	- desc: called when the inputs text
--]]---------------------------------------------------------
function newobject:textinput(text)

	if text:find("kp.") then
		text = text:gsub("kp", "")
	end
		
	self:RunKey(text, true)
	
end

--[[---------------------------------------------------------
	- func: RunKey(key, istext)
	- desc: runs a key event on the object
--]]---------------------------------------------------------
function newobject:RunKey(key, istext)

	
	local visible = self.visible
	local focus = self.focus
	
	if not visible then
		return
	end
	
	if not focus then
		return
	end
	
	local x = self.x
	local offsetx = self.offsetx
	local lines = self.lines
	local line = self.line
	local numlines = #lines
	local curline = lines[line]
	local text = curline
	local ckey = ""
	local font = self.font
	local swidth = self.width
	local textoffsetx = self.textoffsetx
	local indicatornum = self.indicatornum
	local multiline = self.multiline
	local alltextselected = self.alltextselected
	local editable = self.editable
	local initialtext = self:GetText()
	local ontextchanged = self.OnTextChanged
	local onenter = self.OnEnter
	
	if not istext then
		if key == "left" then
			indicatornum = self.indicatornum
			if not multiline then
				self:MoveIndicator(-1)
				local indicatorx = self.indicatorx
				if indicatorx <= x and indicatornum ~= 0 then
					local width = font:getWidth((utf8.sub2(text,indicatornum, indicatornum + 1)))
					self.offsetx = offsetx - width
				elseif indicatornum == 0 and offsetx ~= 0 then
					self.offsetx = 0
				end
			else
				if indicatornum == 0 then
					if line > 1 then
						self.line = line - 1
						local numchars = #lines[self.line]
						self:MoveIndicator(numchars)
					end
				else
					self:MoveIndicator(-1)
				end
			end
			if alltextselected then
				self.line = 1
				self.indicatornum = 0
				self.alltextselected = false
			end
			return
		elseif key == "right" then
			indicatornum = self.indicatornum
			if not multiline then
				self:MoveIndicator(1)
				local indicatorx = self.indicatorx
				if indicatorx >= (x + swidth) and indicatornum ~= #text then
					local width = font:getWidth((utf8.sub2(text,indicatornum, indicatornum)))
					self.offsetx = offsetx + width
				elseif indicatornum == #text and offsetx ~= ((font:getWidth(text)) - swidth + 10) and font:getWidth(text) + textoffsetx > swidth then
					self.offsetx = ((font:getWidth(text)) - swidth + 10)
				end
			else
				if indicatornum == #text then
					if line < numlines then
						self.line = line + 1
						self:MoveIndicator(0, true)
					end
				else
					self:MoveIndicator(1)
				end
			end
			if alltextselected then
				self.line = #lines
				self.indicatornum = lines[#lines]:len()
				self.alltextselected = false
			end
			return
		elseif key == "up" then
			if multiline then
				if line > 1 then
					self.line = line - 1
					if indicatornum > #lines[self.line] then
						self.indicatornum = #lines[self.line]
					end
				end
			end
			return
		elseif key == "down" then
			if multiline then
				if line < #lines then
					self.line = line + 1
					if indicatornum > #lines[self.line] then
						self.indicatornum = #lines[self.line]
					end
				end
			end
			return
		end
		
		if not editable then
			return
		end
		
		-- key input checking system
		if key == "backspace" then
			ckey = key
			if alltextselected then
				self:Clear()
				self.alltextselected = false
				indicatornum = self.indicatornum
			else
				if text ~= "" and indicatornum ~= 0 then
					text = self:RemoveFromText(indicatornum)
					self:MoveIndicator(-1)
					lines[line] = text
				end
				if multiline then
					if line > 1 and indicatornum == 0 then
						local newindicatornum = 0
						local oldtext = lines[line]
						table.remove(lines, line)
						self.line = line - 1
						if #oldtext > 0 then
							newindicatornum = #lines[self.line]
							lines[self.line] = lines[self.line] .. oldtext
							self:MoveIndicator(newindicatornum)
						else
							self:MoveIndicator(#lines[self.line])
						end
					end
				end
				local masked = self.masked
				local cwidth = 0
				if masked then
					local maskchar = self.maskchar
					cwidth = font:getWidth(utf8.sub2(text,#text):gsub(".", maskchar))
				else
					cwidth = font:getWidth(utf8.sub2(text,#text))
				end
				if self.offsetx > 0 then
					self.offsetx = self.offsetx - cwidth
				elseif self.offsetx < 0 then
					self.offsetx = 0
				end
			end
		elseif key == "delete" then
			if not editable then
				return
			end
			ckey = key
			if alltextselected then
				self:Clear()
				self.alltextselected = false
				indicatornum = self.indicatornum
			else
				if text ~= "" and indicatornum < #text then
					text = self:RemoveFromText(indicatornum + 1)
					lines[line] = text
				elseif indicatornum == #text and line < #lines then
					local oldtext = lines[line + 1]
					if #oldtext > 0 then
						newindicatornum = #lines[self.line]
						lines[self.line] = lines[self.line] .. oldtext
					end
					table.remove(lines, line + 1)
				end
			end
		elseif key == "return" or key == "kpenter" then
			ckey = key
			-- call onenter if it exists
			if onenter then
				onenter(self, text)
			end
			-- newline calculations for multiline mode
			if multiline then
				if alltextselected then
					self.alltextselected = false
					self:Clear()
					indicatornum = self.indicatornum
					line = self.line
				end
				local newtext = "" 
				if indicatornum == 0 then
					newtext = self.lines[line]
					self.lines[line] = ""
				elseif indicatornum > 0 and indicatornum < #self.lines[line] then
					newtext = utf8.sub2(self.lines[line],indicatornum + 1, #self.lines[line])
					self.lines[line] = utf8.sub2(self.lines[line],1, indicatornum)
				end
				if line ~= #lines then
					table.insert(self.lines, line + 1, newtext)
					self.line = line + 1
				else
					table.insert(self.lines, newtext)
					self.line = line + 1
				end
				self.indicatornum = 0
			end
		elseif key == "tab" then
			if alltextselected then
				return
			end
			ckey = key
			self.lines[self.line] = self:AddIntoText(self.tabreplacement, self.indicatornum)
			self:MoveIndicator(#self.tabreplacement)
		end
	else
		if not editable then
			return
		end
		-- do not continue if the text limit has been reached or exceeded
		if #text >= self.limit and self.limit ~= 0 and not alltextselected then
			return
		end
		-- check for unusable characters
		if #self.usable > 0 then
			local found = false
			for k, v in ipairs(self.usable) do
				if v == key then
					found = true
				end
			end
			if not found then
				return
			end
		end
		-- check for usable characters
		if #self.unusable > 0 then
			local found = false
			for k, v in ipairs(self.unusable) do
				if v == key then
					found = true
				end
			end
			if found then
				return
			end
		end
		if alltextselected then
			self.alltextselected = false
			self:Clear()
			indicatornum = self.indicatornum
			text = ""
			lines = self.lines
			line = self.line
		end
		if indicatornum ~= 0 and indicatornum ~= #text then
			text = self:AddIntoText(key, indicatornum)
			lines[line] = text
			self:MoveIndicator(1)
		elseif indicatornum == #text then
			text = text .. key
			lines[line] = text
			self:MoveIndicator(1)
		elseif indicatornum == 0 then
			text = self:AddIntoText(key, indicatornum)
			lines[line] = text
			self:MoveIndicator(1)
		end
		lines = self.lines
		line = self.line
		curline = lines[line]
		text = curline
		if not multiline then
			local masked = self.masked
			local twidth = 0
			local cwidth = 0
			if masked then
				local maskchar = self.maskchar
				twidth = font:getWidth(text:gsub(".", maskchar))
				cwidth = font:getWidth(key:gsub(".", maskchar))
			else
				twidth = font:getWidth(text)
				cwidth = font:getWidth(key)
			end
			-- swidth - 1 is for the "-" character
			if (twidth + textoffsetx) >= (swidth - 1) then
				self.offsetx = self.offsetx + cwidth
			end
		end
	end
	
	local curtext = self:GetText()
	if ontextchanged and initialtext ~= curtext then
		ontextchanged(self, key)
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: MoveIndicator(num, exact)
	- desc: moves the object's indicator
--]]---------------------------------------------------------
function newobject:MoveIndicator(num, exact)

	local lines = self.lines
	local line = self.line
	local curline = lines[line]
	local text = curline
	local indicatornum = self.indicatornum
	
	if not exact then
		self.indicatornum = indicatornum + num
	else
		self.indicatornum = num
	end
	
	if self.indicatornum > #text then
		self.indicatornum = #text
	elseif self.indicatornum < 0 then
		self.indicatornum = 0
	end
	
	self.showindicator = true
	self:UpdateIndicator()
	
	return self
	
end

--[[---------------------------------------------------------
	- func: UpdateIndicator()
	- desc: updates the object's text insertion position 
			indicator
--]]---------------------------------------------------------
function newobject:UpdateIndicator()

	local time = love.timer.getTime()
	local indincatortime = self.indincatortime
	local indicatornum = self.indicatornum
	local lines = self.lines
	local line = self.line
	local curline = lines[line]
	local text = curline
	local font = self.font
	local theight = font:getHeight()
	local offsetx = self.offsetx
	local multiline = self.multiline
	local showindicator = self.showindicator
	local alltextselected = self.alltextselected
	local textx = self.textx
	local texty = self.texty
	local masked = self.masked
	
	if indincatortime < time then
		if showindicator then
			self.showindicator = false
		else
			self.showindicator = true
		end
		self.indincatortime = time + 0.50
	end
	
	if alltextselected then
		self.showindicator = false
	end
	
	local width = 0
	
	for i=1, indicatornum do
		if masked then
			local char = self.maskchar
			width = width + font:getWidth(char)
		else
			local char = utf8.sub2(text,i, i)
			width = width + font:getWidth(char)
		end
	end
	
	if multiline then
		self.indicatorx = textx + width
		self.indicatory	= texty + theight * line - theight
	else
		self.indicatorx = textx + width
		self.indicatory	= texty
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: AddIntoText(t, p)
	- desc: adds text into the object's text at a given 
			position
--]]---------------------------------------------------------
function newobject:AddIntoText(t, p)

	local lines = self.lines
	local line = self.line
	local curline = lines[line]
	local text = curline
	local part1 = utf8.sub2(text,1, p)
	local part2 = utf8.sub2(text,p + 1)
	local new = part1 .. t .. part2
	
	return new
	
end

--[[---------------------------------------------------------
	- func: RemoveFromText(p)
	- desc: removes text from the object's text a given 
			position
--]]---------------------------------------------------------
function newobject:RemoveFromText(p)

	local lines = self.lines
	local line = self.line
	local curline = lines[line]
	local text = curline
	local part1 = utf8.sub2(text,1, p - 1)
	local part2 = utf8.sub2(text,p + 1)
	local new = part1 .. part2
	return new
	
end

--[[---------------------------------------------------------
	- func: GetTextCollisions(x, y)
	- desc: gets text collisions with the mouse
--]]---------------------------------------------------------
function newobject:GetTextCollisions(x, y)

	local font = self.font
	local lines = self.lines
	local numlines = #lines
	local line = self.line
	local curline = lines[line]
	local text = curline
	local xpos = 0
	local line = 0
	local vbar = self.vbar
	local hbar = self.hbar
	local multiline = self.multiline
	local selfx = self.x
	local selfy = self.y
	local selfwidth = self.width
	local masked = self.masked
			
	if multiline then
		local theight = font:getHeight()
		local liney = 0
		local selfcol
		if vbar and not hbar then
			selfcol = loveframes.util.BoundingBox(selfx, x, selfy, y, selfwidth - 16, 1, self.height, 1)
		elseif hbar and not vbar then
			selfcol = loveframes.util.BoundingBox(selfx, x, selfy, y, selfwidth, 1, self.height - 16, 1)
		elseif not vbar and not hbar then
			selfcol = loveframes.util.BoundingBox(selfx, x, selfy, y, selfwidth, 1, self.height, 1)
		elseif vbar and hbar then
			selfcol = loveframes.util.BoundingBox(selfx, x, selfy, y, selfwidth - 16, 1, self.height - 16, 1)
		end
		if selfcol then
			local offsety = self.offsety
			local textoffsety = self.textoffsety
			for i=1, numlines do
				local linecol = loveframes.util.BoundingBox(selfx, x, (selfy - offsety) + textoffsety + (theight * i) - theight, y, self.width, 1, theight, 1)
				if linecol then
					liney = (selfy - offsety) + textoffsety + (theight * i) - theight
					self.line = i
				end
			end
			local line = self.line
			local curline = lines[line]
			for i=1, #curline do
				local char = utf8.sub2(text,i, i)
				local width = 0
				if masked then
					local maskchar = self.maskchar
					width = font:getWidth(maskchar)
				else
					width = font:getWidth(char)
				end
				local height = font:getHeight()
				local tx = self.textx + xpos
				local ty = self.texty
				local col = loveframes.util.BoundingBox(tx, x, liney, y, width, 1, height, 1)
				
				xpos = xpos + width
				
				if col then
					self:MoveIndicator(i - 1, true)
					break
				else
					self.indicatornum = #curline
				end
				
				if x < tx then
					self:MoveIndicator(0, true)
				end
				
				if x > (tx + width) then
					self:MoveIndicator(#curline, true)
				end
			end
			
			if #curline == 0 then
				self.indicatornum = 0
			end
		end
	else
		for i=1, #text do
			local char = utf8.sub2(text,i, i)
			local width = 0
			if masked then
				local maskchar = self.maskchar
				width = font:getWidth(maskchar)
			else
				width = font:getWidth(char)
			end
			local height = font:getHeight()
			local tx = self.textx + xpos
			local ty = self.texty
			local col = loveframes.util.BoundingBox(tx, x, ty, y, width, 1, height, 1)
			xpos = xpos + width
			if col then
				self:MoveIndicator(i - 1, true)
				break
			end
			if x < tx then
				self:MoveIndicator(0, true)
			end
			if x > (tx + width) then
				self:MoveIndicator(#text, true)
			end
		end
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: PositionText()
	- desc: positions the object's text
--]]---------------------------------------------------------
function newobject:PositionText()

	local multiline = self.multiline
	local x = self.x
	local y = self.y
	local offsetx = self.offsetx
	local offsety = self.offsety
	local textoffsetx = self.textoffsetx
	local textoffsety = self.textoffsety
	local linenumberspanel = self.linenumberspanel
	
	if multiline then
		if linenumberspanel then
			local panel = self:GetLineNumbersPanel()
			self.textx = ((x + panel.width) - offsetx) + textoffsetx
			self.texty = (y - offsety) + textoffsety
		else
			self.textx = (x - offsetx) + textoffsetx
			self.texty = (y - offsety) + textoffsety
		end
	else
		self.textx = (x - offsetx) + textoffsetx
		self.texty = (y - offsety) + textoffsety
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: SetTextOffsetX(num)
	- desc: sets the object's text x offset
--]]---------------------------------------------------------
function newobject:SetTextOffsetX(num)

	self.textoffsetx = num
	return self
	
end

--[[---------------------------------------------------------
	- func: SetTextOffsetY(num)
	- desc: sets the object's text y offset
--]]---------------------------------------------------------
function newobject:SetTextOffsetY(num)

	self.textoffsety = num
	return self
	
end

--[[---------------------------------------------------------
	- func: SetFont(font)
	- desc: sets the object's font
--]]---------------------------------------------------------
function newobject:SetFont(font)

	self.font = font
	return self
	
end

--[[---------------------------------------------------------
	- func: GetFont()
	- desc: gets the object's font
--]]---------------------------------------------------------
function newobject:GetFont()

	return self.font
	
end

--[[---------------------------------------------------------
	- func: SetFocus(focus)
	- desc: sets the object's focus
--]]---------------------------------------------------------
function newobject:SetFocus(focus)

	local inputobject = loveframes.inputobject
	local onfocusgained = self.OnFocusGained
	local onfocuslost = self.OnFocusLost
	
	self.focus = focus
	
	if focus then
		loveframes.inputobject = self
		if onfocusgained then
			onfocusgained(self)
		end
	else
		if inputobject == self then
			loveframes.inputobject = false
		end
		if onfocuslost then
			onfocuslost(self)
		end
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: GetFocus()
	- desc: gets the object's focus
--]]---------------------------------------------------------
function newobject:GetFocus()

	return self.focus
	
end

--[[---------------------------------------------------------
	- func: GetIndicatorVisibility()
	- desc: gets the object's indicator visibility
--]]---------------------------------------------------------
function newobject:GetIndicatorVisibility()

	return self.showindicator
	
end

--[[---------------------------------------------------------
	- func: SetLimit(limit)
	- desc: sets the object's text limit
--]]---------------------------------------------------------
function newobject:SetLimit(limit)

	self.limit = limit
	return self
	
end

--[[---------------------------------------------------------
	- func: SetUsable(usable)
	- desc: sets what characters can be used for the 
			object's text
--]]---------------------------------------------------------
function newobject:SetUsable(usable)

	self.usable = usable
	return self
	
end

--[[---------------------------------------------------------
	- func: GetUsable()
	- desc: gets what characters can be used for the 
			object's text
--]]---------------------------------------------------------
function newobject:GetUsable()

	return self.usable
	
end

--[[---------------------------------------------------------
	- func: SetUnusable(unusable)
	- desc: sets what characters can not be used for the 
			object's text
--]]---------------------------------------------------------
function newobject:SetUnusable(unusable)

	self.unusable = unusable
	return self
	
end

--[[---------------------------------------------------------
	- func: GetUnusable()
	- desc: gets what characters can not be used for the 
			object's text
--]]---------------------------------------------------------
function newobject:GetUnusable()

	return self.unusable
	
end

--[[---------------------------------------------------------
	- func: Clear()
	- desc: clears the object's text
--]]---------------------------------------------------------
function newobject:Clear()

	self.lines = {""}
	self.line = 1
	self.offsetx = 0
	self.offsety = 0
	self.indicatornum = 0
	
	return self
	
end

--[[---------------------------------------------------------
	- func: SetText(text)
	- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)

	local tabreplacement = self.tabreplacement
	local multiline = self.multiline
	
	text = tostring(text)
	text = text:gsub(string.char(9), tabreplacement)
	text = text:gsub(string.char(13), "")
	
	if multiline then
		text = text:gsub(string.char(92) .. string.char(110), string.char(10))
		local t = loveframes.util.SplitString(text, string.char(10))
		if #t > 0 then
			self.lines = t
		else
			self.lines = {""}
		end
		self.line = #self.lines
		self.indicatornum = #self.lines[#self.lines]
	else
		text = text:gsub(string.char(92) .. string.char(110), "")
		text = text:gsub(string.char(10), "")
		self.lines = {text}
		self.line = 1
		self.indicatornum = #text
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: GetText()
	- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()

	local multiline = self.multiline
	local lines = self.lines
	local text = ""
	
	if multiline then
		for k, v in ipairs(lines) do
			text = text .. v
			if k ~= #lines then
				text = text .. "\n"
			end
		end
	else
		text = lines[1]
	end
	
	return text
	
end

--[[---------------------------------------------------------
	- func: SetMultiline(bool)
	- desc: enables or disables allowing multiple lines for
			text entry
--]]---------------------------------------------------------
function newobject:SetMultiline(bool)

	local text = ""
	local lines = self.lines
	
	self.multiline = bool
	
	if bool then
		self:Clear()
	else
		for k, v in ipairs(lines) do
			text = text .. v
		end
		self:SetText(text)
		self.internals = {}
		self.vbar = false
		self.hbar = false
		self.linenumberspanel = false
	end
	
	return self

end

--[[---------------------------------------------------------
	- func: GetMultiLine()
	- desc: gets whether or not the object is using multiple
			lines
--]]---------------------------------------------------------
function newobject:GetMultiLine()

	return self.multiline
	
end

--[[---------------------------------------------------------
	- func: GetVerticalScrollBody()
	- desc: gets the object's vertical scroll body
--]]---------------------------------------------------------
function newobject:GetVerticalScrollBody()

	local vbar = self.vbar
	local internals = self.internals
	local item = false
	
	if vbar then
		for k, v in ipairs(internals) do
			if v.type == "scrollbody" and v.bartype == "vertical" then
				item = v
			end
		end
	end
	
	return item

end

--[[---------------------------------------------------------
	- func: GetHorizontalScrollBody()
	- desc: gets the object's horizontal scroll body
--]]---------------------------------------------------------
function newobject:GetHorizontalScrollBody()

	local hbar = self.hbar
	local internals = self.internals
	local item = false
	
	if hbar then
		for k, v in ipairs(internals) do
			if v.type == "scrollbody" and v.bartype == "horizontal" then
				item = v
			end
		end
	end
	
	return item

end

--[[---------------------------------------------------------
	- func: HasVerticalScrollBar()
	- desc: gets whether or not the object has a vertical
			scroll bar
--]]---------------------------------------------------------
function newobject:HasVerticalScrollBar()

	return self.vbar
	
end

--[[---------------------------------------------------------
	- func: HasHorizontalScrollBar()
	- desc: gets whether or not the object has a horizontal
			scroll bar
--]]---------------------------------------------------------
function newobject:HasHorizontalScrollBar()

	return self.hbar
	
end

--[[---------------------------------------------------------
	- func: GetLineNumbersPanel()
	- desc: gets the object's line numbers panel
--]]---------------------------------------------------------
function newobject:GetLineNumbersPanel()

	local panel = self.linenumberspanel
	local internals = self.internals
	local item = false
	
	if panel then
		for k, v in ipairs(internals) do
			if v.type == "linenumberspanel" then
				item = v
			end
		end
	end
	
	return item
	
end

--[[---------------------------------------------------------
	- func: ShowLineNumbers(bool)
	- desc: sets whether or not to show line numbers when
			using multiple lines
--]]---------------------------------------------------------
function newobject:ShowLineNumbers(bool)

	local multiline = self.multiline
	
	if multiline then
		self.linenumbers = bool
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: GetTextX()
	- desc: gets the object's text x
--]]---------------------------------------------------------
function newobject:GetTextX()

	return self.textx
	
end

--[[---------------------------------------------------------
	- func: GetTextY()
	- desc: gets the object's text y
--]]---------------------------------------------------------
function newobject:GetTextY()

	return self.texty
	
end

--[[---------------------------------------------------------
	- func: IsAllTextSelected()
	- desc: gets whether or not all of the object's text is
			selected
--]]---------------------------------------------------------
function newobject:IsAllTextSelected()

	return self.alltextselected
	
end

--[[---------------------------------------------------------
	- func: GetLines()
	- desc: gets the object's lines
--]]---------------------------------------------------------
function newobject:GetLines()

	return self.lines
	
end

--[[---------------------------------------------------------
	- func: GetOffsetX()
	- desc: gets the object's x offset
--]]---------------------------------------------------------
function newobject:GetOffsetX()

	return self.offsetx
	
end

--[[---------------------------------------------------------
	- func: GetOffsetY()
	- desc: gets the object's y offset
--]]---------------------------------------------------------
function newobject:GetOffsetY()

	return self.offsety
	
end

--[[---------------------------------------------------------
	- func: GetIndicatorX()
	- desc: gets the object's indicator's xpos
--]]---------------------------------------------------------
function newobject:GetIndicatorX()

	return self.indicatorx
	
end

--[[---------------------------------------------------------
	- func: GetIndicatorY()
	- desc: gets the object's indicator's ypos
--]]---------------------------------------------------------
function newobject:GetIndicatorY()

	return self.indicatory
	
end

--[[---------------------------------------------------------
	- func: GetLineNumbersEnabled()
	- desc: gets whether line numbers are enabled on the
			object or not
--]]---------------------------------------------------------
function newobject:GetLineNumbersEnabled()

	return self.linenumbers
	
end

--[[---------------------------------------------------------
	- func: GetItemWidth()
	- desc: gets the object's item width
--]]---------------------------------------------------------
function newobject:GetItemWidth()

	return self.itemwidth
	
end

--[[---------------------------------------------------------
	- func: GetItemHeight()
	- desc: gets the object's item height
--]]---------------------------------------------------------
function newobject:GetItemHeight()

	return self.itemheight
	
end

--[[---------------------------------------------------------
	- func: SetTabReplacement(tabreplacement)
	- desc: sets a string to replace tabs with
--]]---------------------------------------------------------
function newobject:SetTabReplacement(tabreplacement)

	self.tabreplacement = tabreplacement
	return self
	
end

--[[---------------------------------------------------------
	- func: GetTabReplacement()
	- desc: gets the object's tab replacement
--]]---------------------------------------------------------
function newobject:GetTabReplacement()

	return self.tabreplacement
	
end

--[[---------------------------------------------------------
	- func: SetEditable(bool)
	- desc: sets whether or not the user can edit the
			object's text
--]]---------------------------------------------------------
function newobject:SetEditable(bool)

	self.editable = bool
	return self
	
end

--[[---------------------------------------------------------
	- func: GetEditable
	- desc: gets whether or not the user can edit the
			object's text
--]]---------------------------------------------------------
function newobject:GetEditable()

	return self.editable
	
end

--[[---------------------------------------------------------
	- func: SetButtonScrollAmount(speed)
	- desc: sets the scroll amount of the object's scrollbar
			buttons
--]]---------------------------------------------------------
function newobject:SetButtonScrollAmount(amount)

	self.buttonscrollamount = amount
	return self
	
end

--[[---------------------------------------------------------
	- func: GetButtonScrollAmount()
	- desc: gets the scroll amount of the object's scrollbar
			buttons
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()

	return self.buttonscrollamount
	
end

--[[---------------------------------------------------------
	- func: SetMouseWheelScrollAmount(amount)
	- desc: sets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:SetMouseWheelScrollAmount(amount)

	self.mousewheelscrollamount = amount
	return self
	
end

--[[---------------------------------------------------------
	- func: GetMouseWheelScrollAmount()
	- desc: gets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()

	return self.mousewheelscrollamount
	
end

--[[---------------------------------------------------------
	- func: SetAutoScroll(bool)
	- desc: sets whether or not the object should autoscroll
			when in multiline mode
--]]---------------------------------------------------------
function newobject:SetAutoScroll(bool)
	
	local internals = self.internals
	
	self.autoscroll = bool
	
	if internals[2] then
		internals[2].internals[1].internals[1].autoscroll = bool
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: GetAutoScroll()
	- desc: gets whether or not the object should autoscroll
			when in multiline mode
--]]---------------------------------------------------------
function newobject:GetAutoScroll()

	return self.autoscroll
	
end

--[[---------------------------------------------------------
	- func: SetRepeatDelay(delay)
	- desc: sets the object's repeat delay
--]]---------------------------------------------------------
function newobject:SetRepeatDelay(delay)

	self.repeatdelay = delay
	return self
	
end

--[[---------------------------------------------------------
	- func: GetRepeatDelay()
	- desc: gets the object's repeat delay
--]]---------------------------------------------------------
function newobject:GetRepeatDelay()

	return self.repeatdelay
	
end

--[[---------------------------------------------------------
	- func: SetRepeatRate(rate)
	- desc: sets the object's repeat rate
--]]---------------------------------------------------------
function newobject:SetRepeatRate(rate)

	self.repeatrate = rate
	return self
	
end

--[[---------------------------------------------------------
	- func: GetRepeatRate()
	- desc: gets the object's repeat rate
--]]---------------------------------------------------------
function newobject:GetRepeatRate()

	return self.repeatrate
	
end

--[[---------------------------------------------------------
	- func: SetValue(value)
	- desc: sets the object's value (alias of SetText)
--]]---------------------------------------------------------
function newobject:SetValue(value)

	self:SetText(value)
	return self
	
end

--[[---------------------------------------------------------
	- func: GetValue()
	- desc: gets the object's value (alias of GetText)
--]]---------------------------------------------------------
function newobject:GetValue()

	return self:GetText()
	
end

--[[---------------------------------------------------------
	- func: SetVisible(bool)
	- desc: sets the object's visibility
--]]---------------------------------------------------------
function newobject:SetVisible(bool)

	self.visible = bool
	
	if not bool then
		self.keydown = "none"
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: Copy()
	- desc: copies the object's text to the user's clipboard
--]]---------------------------------------------------------
function newobject:Copy()

	local text = self:GetText()
	love.system.setClipboardText(text)
	
	return self
	
end

--[[---------------------------------------------------------
	- func: Paste()
	- desc: pastes the current contents of the clipboard 
			into the object's text
--]]---------------------------------------------------------
function newobject:Paste()
	
	local text = love.system.getClipboardText()
	local usable = self.usable
	local unusable = self.unusable
	local limit = self.limit
	local alltextselected = self.alltextselected
	local onpaste = self.OnPaste
	local ontextchanged = self.OnTextChanged
	
	if limit > 0 then
		local curtext = self:GetText()
		local curlength = curtext:len()
		if curlength == limit then
			return
		else
			local inputlimit = limit - curlength
			if text:len() > inputlimit then
				text = utf8.sub2(text,1, inputlimit)
			end
		end
	end
	local charcheck = function(a)
		if #usable > 0 then
			if not loveframes.util.TableHasValue(usable, a) then
				return ""
			end
		elseif #unusable > 0 then
			if loveframes.util.TableHasValue(unusable, a) then
				return ""
			end
		end
	end
	if #usable > 0 or #unusable > 0 then
		text = text:gsub(".", charcheck)
	end
	if alltextselected then
		self:SetText(text)
		self.alltextselected = false
		if ontextchanged then
			ontextchanged(self, text)
		end
	else
		local tabreplacement = self.tabreplacement
		local indicatornum = self.indicatornum
		local lines = self.lines
		local multiline = self.multiline
		if multiline then
			local parts = loveframes.util.SplitString(text, string.char(10))
			local numparts = #parts
			local oldlinedata = {}
			local line = self.line
			local first = utf8.sub2(lines[line],0, indicatornum)
			local last = utf8.sub2(lines[line],indicatornum + 1)
			if numparts > 1 then
				for i=1, numparts do
					local part = parts[i]:gsub(string.char(13),  "")
					part = part:gsub(string.char(9), "    ")
					if i ~= 1 then
						table.insert(oldlinedata, lines[line])
						lines[line] = part
						if i == numparts then
							self.indicatornum = part:len()
							lines[line] = lines[line] .. last
							self.line = line
						end
					else
						lines[line] = first .. part
					end
					line = line + 1
				end
				for i=1, #oldlinedata do
					lines[line] = oldlinedata[i]
					line = line + 1
				end
				if ontextchanged then
					ontextchanged(self, text)
				end
			elseif numparts == 1 then
				text = text:gsub(string.char(10), " ")
				text = text:gsub(string.char(13), " ")
				text = text:gsub(string.char(9), tabreplacement)
				local length = text:len()
				local new = first .. text .. last
				lines[line] = new
				self.indicatornum = indicatornum + length
				if ontextchanged then
					ontextchanged(self, text)
				end
			end
		else
			text = text:gsub(string.char(10), " ")
			text = text:gsub(string.char(13), " ")
			text = text:gsub(string.char(9), tabreplacement)
			local length = text:len()
			local linetext = lines[1]
			local part1 = utf8.sub2(linetext,1, indicatornum)
			local part2 = utf8.sub2(linetext,indicatornum + 1)
			local new = part1 .. text .. part2
			lines[1] = new
			self.indicatornum = indicatornum + length
			if ontextchanged then
				ontextchanged(self, text)
			end
		end
	end
	if onpaste then
		onpaste(self, text)
	end
	
	return self
	
end

--[[---------------------------------------------------------
	- func: SelectAll()
	- desc: selects all of the object's text
--]]---------------------------------------------------------
function newobject:SelectAll()

	if not self.multiline then
		if self.lines[1] ~= "" then
			self.alltextselected = true
		end
	else
		self.alltextselected = true
	end

	return self
	
end

--[[---------------------------------------------------------
	- func: DeselectAll()
	- desc: deselects all of the object's text
--]]---------------------------------------------------------
function newobject:DeselectAll()

	self.alltextselected = false
	return self
	
end

--[[---------------------------------------------------------
	- func: SetMasked(masked)
	- desc: sets whether or not the object is masked
--]]---------------------------------------------------------
function newobject:SetMasked(masked)

	self.masked = masked
	return self
	
end

--[[---------------------------------------------------------
	- func: GetMasked()
	- desc: gets whether or not the object is masked
--]]---------------------------------------------------------
function newobject:GetMasked()

	return self.masked
	
end

--[[---------------------------------------------------------
	- func: SetMaskChar(char)
	- desc: sets the object's mask character
--]]---------------------------------------------------------
function newobject:SetMaskChar(char)

	self.maskchar = char
	return self
	
end

--[[---------------------------------------------------------
	- func: GetMaskChar()
	- desc: gets the object's mask character
--]]---------------------------------------------------------
function newobject:GetMaskChar()

	return self.maskchar
	
end

--[[---------------------------------------------------------
	- func: SetPlaceholderText(text)
	- desc: sets the object's placeholder text
--]]---------------------------------------------------------
function newobject:SetPlaceholderText(text)

	self.placeholder = text
	return self
	
end

--[[---------------------------------------------------------
	- func: GetPlaceholderText()
	- desc: gets the object's placeholder text
--]]---------------------------------------------------------
function newobject:GetPlaceholderText()

	return self.placeholder
	
end

User avatar
Nikolai Resokav
Party member
Posts: 140
Joined: Wed Apr 28, 2010 12:51 am
Location: United States

Re: Löve Frames - A GUI Library

Post by Nikolai Resokav » Wed Sep 17, 2014 12:36 am

megalukes wrote:I'm here just to thank you for this library. I was going to start programming an editor for my game from sketch but Löve Frames saved my a lot of time. I'm still impressed about how easy it is to make cool stuff with it. Are there any new features you intend to implement in the future?
Yes, there are many features planned for future releases, though there is no official list.
megalukes wrote:So, I made some snippets here and it works now. Thanks to Kyle Smith's utf8.lua I replaced all those string:sub lines for string.utf8sub in loveframes/objects/textinput.lua.
Awesome! Thats a big step forward, as UTF8 compatibility has been issue with Love Frames for quite some time now. One thing I've noticed however, is that any instances where the length operator (#) is being used on a string will need to be replaced with a call to string.utf8len, as the length operator will not return the correct length of UTF8 string. Other than that, your changes seem to integrate nicely. I'll make a commit soon to add your changes to the repository, or you can make a pull on request on github if you have an account there.

Thanks for contributing!

User avatar
adnzzzzZ
Party member
Posts: 305
Joined: Sun Dec 26, 2010 11:04 pm
Location: Porto Alegre, Brazil

Re: Löve Frames - A GUI Library

Post by adnzzzzZ » Sun Sep 28, 2014 2:40 pm

Anyone knows how to change the color of a button's text?

Image

I wanna make the + green and - red.

User avatar
Nikolai Resokav
Party member
Posts: 140
Joined: Wed Apr 28, 2010 12:51 am
Location: United States

Re: Löve Frames - A GUI Library

Post by Nikolai Resokav » Sun Sep 28, 2014 6:33 pm

adnzzzzZ wrote:Anyone knows how to change the color of a button's text?

Image

I wanna make the + green and - red.
You can change their color in the button drawing function in skin.lua.

Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests