textinput.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. ---------------
  2. -- TEXT INPUT
  3. ---------------
  4. goo.textinput = class('goo text input', goo.object)
  5. function goo.textinput:initialize( parent )
  6. super.initialize(self,parent)
  7. self.text = ''
  8. self.textXoffset = 0
  9. self.focus = false
  10. self.blink = false
  11. self.blinkRate = self.style.blinkRate
  12. self.blinkTime = love.timer.getTime() + self.blinkRate
  13. self.font = self.style.textFont
  14. self.fontH = self.font:getHeight()
  15. self.caretPos = 1
  16. self.lines = {}
  17. self.lines[1] = ''
  18. self.linePos = 1
  19. self.leading = self.style.leading
  20. self.multiline = false
  21. love.keyboard.setKeyRepeat( 500, 50 )
  22. end
  23. function goo.textinput:update(dt)
  24. super.update(self,dt)
  25. if love.timer.getTime() > self.blinkTime then
  26. self.blink = not self.blink
  27. self.blinkTime = love.timer.getTime() + self.blinkRate
  28. end
  29. if love.mouse.isDown('l') and not self.hoverState then self.focus = false end
  30. self.textXoffset = self.font:getWidth( self.lines[self.linePos]:sub(1,self.caretPos) ) - self.w + 15
  31. if self.textXoffset < 0 then self.textXoffset = 0 end
  32. if self.caretPos < 1 then self.caretPos = 1 end
  33. end
  34. function goo.textinput:draw(x,y)
  35. local x,y = self:getAbsolutePos()
  36. if self.style.textFont then
  37. love.graphics.setFont( self.style.textFont )
  38. else
  39. love.graphics.setFont( 12 )
  40. end
  41. self.font = love.graphics.getFont()
  42. self.fontH = self.font:getHeight()
  43. local w = self.style.borderWidth
  44. self:setColor( self.style.borderColor )
  45. love.graphics.rectangle('fill',-w,-w,self.w+(w*2),self.h+(w*2))
  46. self:setColor( self.style.backgroundColor )
  47. love.graphics.rectangle('fill',0,0,self.w,self.h)
  48. love.graphics.setScissor( x, y-1, self.w, self.h+1 )
  49. for i,txt in ipairs(self.lines) do
  50. self:setColor( self.style.textColor )
  51. love.graphics.print( txt, 5-self.textXoffset, (self.fontH)+(self.leading*(i-1)))
  52. end
  53. if self.blink and self.focus then
  54. self:setColor( self.style.cursorColor )
  55. local w = self.font:getWidth( self.lines[self.linePos]:sub(1,self.caretPos-1) )
  56. w = math.min( w, self.w - 15 )
  57. love.graphics.rectangle('fill', w+5, 2+(self.leading*(self.linePos-1)), self.style.cursorWidth, self.fontH)
  58. end
  59. love.graphics.setScissor()
  60. end
  61. function goo.textinput:keypressed(key,unicode)
  62. if not self.focus then return false end
  63. if key == 'backspace' then
  64. self:keyBackspace()
  65. elseif key == 'return' then
  66. self:keyReturn()
  67. elseif key == 'left' then
  68. self:keyLeft()
  69. elseif key == 'right' then
  70. self:keyRight()
  71. elseif key == 'up' then
  72. self:keyUp()
  73. elseif key == 'down' then
  74. self:keyDown()
  75. elseif unicode ~= 0 and unicode < 1000 then
  76. self:keyText(key,unicode)
  77. end
  78. if self.onKeypressed then self:onKeypressed( key, unicode ) end
  79. return true
  80. end
  81. function goo.textinput:keyText(key,unicode)
  82. self:insert(string.char(unicode), self.caretPos)
  83. self.caretPos = self.caretPos + 1
  84. end
  85. function goo.textinput:keyReturn()
  86. if self.onkeyReturn then self:onKeyReturn() end
  87. if not self.multiline then return end
  88. if self.caretPos > self.lines[self.linePos]:len() then
  89. self.linePos = self.linePos + 1
  90. self.caretPos = 1
  91. self:newline( self.linePos )
  92. else
  93. self:newlineWithText( self.caretPos, self.linePos )
  94. end
  95. end
  96. function goo.textinput:keyBackspace()
  97. if self.caretPos == 1 and self.linePos > 1 then
  98. if not self.multiline then return end
  99. self:backspaceLine( self.linePos )
  100. else
  101. self:remove(self.caretPos,1)
  102. self.caretPos = self.caretPos - 1
  103. end
  104. end
  105. function goo.textinput:keyLeft()
  106. if self.caretPos > 1 then
  107. self.caretPos = self.caretPos - 1
  108. if self.caretPos < 1 then self.caretPos = 1 end
  109. else
  110. if self.linePos > 1 then
  111. if not self.multiline then return end
  112. self.linePos = self.linePos - 1
  113. self.caretPos = self.lines[self.linePos]:len()+1
  114. end
  115. end
  116. end
  117. function goo.textinput:keyRight()
  118. if self.caretPos <= self.lines[self.linePos]:len() then
  119. self.caretPos = self.caretPos + 1
  120. else
  121. if not self.multiline then return end
  122. if self.linePos < #self.lines then
  123. self.linePos = self.linePos+1
  124. self.caretPos = 1
  125. end
  126. end
  127. end
  128. function goo.textinput:keyUp()
  129. if not self.multiline then return end
  130. if self.linePos == 1 then return end
  131. self.linePos = self.linePos - 1
  132. end
  133. function goo.textinput:keyDown()
  134. if not self.multiline then return end
  135. if self.linePos == #self.lines then return end
  136. self.linePos = self.linePos + 1
  137. end
  138. function goo.textinput:insert(text,pos)
  139. local txt = self.lines[self.linePos]
  140. local part1 = txt:sub(1,pos-1)
  141. local part2 = txt:sub(pos)
  142. self.lines[self.linePos] = part1 .. text .. part2
  143. end
  144. function goo.textinput:remove(pos,length)
  145. if pos == 1 then return end
  146. local txt = self.lines[self.linePos]
  147. local part1 = txt:sub(1,pos-2)
  148. local part2 = txt:sub(pos+length-1)
  149. self.lines[self.linePos] = part1 .. part2
  150. end
  151. function goo.textinput:newline(pos)
  152. local pos = pos or nil
  153. table.insert(self.lines,pos,'')
  154. end
  155. function goo.textinput:removeline(pos)
  156. local pos = pos or #self.lines
  157. table.remove(self.lines,pos)
  158. end
  159. function goo.textinput:backspaceLine()
  160. local _line = self.lines[self.linePos]
  161. self:removeline( self.linePos )
  162. self.linePos = self.linePos - 1
  163. self.caretPos = self.lines[self.linePos]:len()+1
  164. self.lines[self.linePos] = self.lines[self.linePos] .. _line
  165. end
  166. function goo.textinput:newlineWithText(pos,pos2)
  167. local part1 = self.lines[self.linePos]:sub(1,pos-1)
  168. local part2 = self.lines[self.linePos]:sub(pos)
  169. self.lines[pos2] = part1
  170. self:newline(self.linePos+1)
  171. self.linePos = self.linePos + 1
  172. self.caretPos = 1
  173. self.lines[self.linePos] = part2
  174. end
  175. function goo.textinput:mousepressed( x, y, button )
  176. self.focus = true
  177. end
  178. function goo.textinput:getText()
  179. local text = ''
  180. for i,v in ipairs(self.lines) do
  181. text = text .. v .. '\n'
  182. end
  183. return text
  184. end
  185. function goo.textinput:setText( text )
  186. self.lines = {}
  187. if not self.multiline then
  188. local str = text:gsub('\n','')
  189. self.lines[1] = str
  190. self.caretPos = str:len()+1
  191. else
  192. local count = 1
  193. for line in string.match( text, '(.*)\n' ) do
  194. self.lines[ count ] = line
  195. count = count + 1
  196. end
  197. end
  198. end
  199. -- Getters Setters
  200. goo.textinput:getterSetter( 'multiline', false )
  201. goo.textinput:getterSetter( 'linePos', 1 )
  202. goo.textinput:getterSetter( 'caretPos', 1 )
  203. return goo.textinput