textbuffer.lua 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. --This library is create for programming code editors in liko-12 more easly by using premade text buffer with horizental and vertical scrolling support--
  2. local tb = _Class("liko12.textBuffer")
  3. --Args: grid x, grid Y, draw width in grid, draw height in grid, lines Limit, length Limit, min length, cursor color, blinktime--
  4. --0 blinktime disables cursor, 0 lines limit, 0 length disables all that..--
  5. --TODO: add real lines & length & mlength limits.--
  6. function tb:initialize(gx,gy,gw,gh,linel,lengthl,mlength,curcol,blinktime)
  7. self.gx, self.gy, self.linel, self.lenl, self.minl, self.curcol, self.blinktime = gx or 1, gy or 1, linel or 16, lengthl or 47, mlength or 0, curcol or 5, blinktime or 0.5
  8. self.gw, self.gh = gw or self.lenl, gh or self.linel
  9. self.buffer = {""} --Start with an empty line
  10. self.blinktimer = 0
  11. self.blinkstate = 0
  12. self.cursorX, self.cursorY = 1,1
  13. self.lastCX = 1 --Last cursor x when scrolling up or down
  14. self.shiftRight = 0
  15. self.shiftTop = 0
  16. self.keymap = {
  17. ["return"] = function(self,ir)
  18. self:shiftDown(self.cursorY+1)
  19. self.buffer[self.cursorY+1] = self.buffer[self.cursorY]:sub(self.cursorX,-1)
  20. self.buffer[self.cursorY] = self.buffer[self.cursorY]:sub(0,self.cursorX-1)
  21. self.cursorY = self.cursorY+1
  22. self.cursorX = 1
  23. end,
  24. ["backspace"] = function(self,ir)
  25. if self.cursorX == 1 then --If it's at the start of the line
  26. if self.buffer[self.cursorY-1] then
  27. self.cursorX = self.buffer[self.cursorY-1]:len()+1
  28. self.buffer[self.cursorY-1] = self.buffer[self.cursorY-1]..self.buffer[self.cursorY]
  29. self:shiftUp(self.cursorY+1)
  30. self.cursorY = self.cursorY-1
  31. end
  32. else
  33. self.buffer[self.cursorY] = self.buffer[self.cursorY]:sub(0,self.cursorX-2)..self.buffer[self.cursorY]:sub(self.cursorX,-1)
  34. self.cursorX = self.cursorX-1
  35. end
  36. end,
  37. ["left"] = function(self,ir)
  38. self.cursorX = self.cursorX-1
  39. if self.cursorX < 1 then
  40. if self.buffer[self.cursorY-1] then
  41. self.cursorX = self.buffer[self.cursorY-1]:len()+1
  42. self.keymap["up"](self,false)
  43. else
  44. self.cursorX = 1
  45. end
  46. end
  47. end,
  48. ["right"] = function(self,ir)
  49. self.cursorX = self.cursorX+1
  50. if self.cursorX > self.buffer[self.cursorY]:len()+1 then
  51. if self.buffer[self.cursorY+1] then
  52. self.cursorX = 1
  53. self.keymap["down"](self,false)
  54. else
  55. self.cursorX = self.buffer[self.cursorY]:len()+1
  56. end
  57. end
  58. end,
  59. ["up"] = function(self,ir)
  60. if self.buffer[self.cursorY-1] then
  61. self.cursorY = self.cursorY-1
  62. if not ir then self.lastCX = self.cursorX else self.cursorX = self.lastCX end
  63. if self.cursorX > self.buffer[self.cursorY]:len()+1 then self.cursorX = self.buffer[self.cursorY]:len()+1 end
  64. end
  65. end,
  66. ["down"] = function(self,ir)
  67. if self.buffer[self.cursorY+1] then
  68. self.cursorY = self.cursorY+1
  69. if not ir then self.lastCX = self.cursorX else self.cursorX = self.lastCX end
  70. if self.cursorX > self.buffer[self.cursorY]:len()+1 then self.cursorX = self.buffer[self.cursorY]:len()+1 end
  71. end
  72. end,
  73. ["home"] = function(self,ir)
  74. self.cursorX = 1
  75. end,
  76. ["end"] = function(self,ir)
  77. self.cursorX = self.buffer[self.cursorY]:len()+1
  78. end,
  79. ["pageup"] = function(self,ir)
  80. for i=1, self.gh do
  81. end
  82. end,
  83. ["pagedown"] = function(self,ir)
  84. end
  85. }
  86. end
  87. function tb:_update(dt)
  88. if self.blinktime == 0 then return end
  89. self.blinktimer = self.blinktimer+dt if self.blinktimer > self.blinktime then self.blinktimer = self.blinktimer - self.blinktime self.blinkstate = not self.blinkstate end
  90. local curlen = self.buffer[self.cursorY]:len()
  91. if self.blinkstate then api.rect((self.cursorX-1-self.shiftRight)*4+2,(self.cursorY-self.shiftTop)*8+2,4,5,self.curcol) else self:_redraw() end
  92. end
  93. function tb:_redraw()
  94. local dbuff = self:getDrawBuffer()
  95. for line,text in ipairs(debuff) do
  96. api.print_grid(line,self.gx,self.gy)
  97. end
  98. end
  99. function tb:_tinput(t)
  100. self:forceBlink()
  101. --print(self.buffer[self.cursorY]:sub(0,self.cursorX-1)..t..self.buffer[self.cursorY]:sub(self.cursorX,-1))
  102. if self.lenl > 0 and self.buffer[self.cursorY]:len()-1 > self.lenl then return end
  103. self.buffer[self.cursorY] = self.buffer[self.cursorY]:sub(0,self.cursorX-1)..t..self.buffer[self.cursorY]:sub(self.cursorX,-1)
  104. self.cursorX = self.cursorX + t:len()
  105. self:_redraw()
  106. end
  107. function tb:getBuffer()
  108. local bclone = {}
  109. for line,text in ipairs(self.buffer) do
  110. table.insert(bclone,text)
  111. end
  112. return bclone
  113. end
  114. function tb:getLinesBuffer()
  115. self:fixShifts()
  116. local dbuff = {}
  117. for y=self.shiftTop+1,self.shiftTop+1+self.gh do
  118. if self.buffer[y] then
  119. table.insert(dbuff,self.buffer[y])
  120. end
  121. end
  122. return dbuff, self.gx, self.gy, self.shiftRight
  123. end
  124. function tb:getDrawBuffer()
  125. self:fixShifts()
  126. local dbuff = {}
  127. for y=self.shiftTop+1,self.shiftTop+1+self.gh do
  128. if self.buffer[y] then
  129. table.insert(dbuff,self.buffer[y]:sub(self.shiftRight,self.shiftRight+self.gw))
  130. end
  131. end
  132. return dbuff, self.gx, self.gy
  133. end
  134. function tb:fixShifts()
  135. if self.cursorX > self.shiftRight+self.gw then self.shiftRight = self.cursorX - self.gw end
  136. if self.cursorY > self.shiftTop+self.gh then self.shiftTop = self.cursorY - self.gh end
  137. if self.cursorX <= self.shiftRight then self.shiftRight = self.cursorX-1 end
  138. if self.cursorY <= self.shiftTop then self.shiftTop = self.cursorY-1 end
  139. self.shiftRight = api.floor(self.shiftRight)
  140. self.shiftTop = api.floor(self.shiftTop)
  141. end
  142. function tb:forceBlink() self.blinktimer, self.blinkstate = 0, true end
  143. function tb:shiftDown(sline) --Note: the sline is shifted
  144. if sline > #self.buffer then table.insert(self.buffer,"") return end
  145. table.insert(self.buffer,"") -- Insert a new line
  146. for i=#self.buffer-1,sline,-1 do
  147. self.buffer[i+1] = self.buffer[i]
  148. end
  149. self.buffer[sline] = "" --Clear the start line
  150. return self
  151. end
  152. function tb:shiftUp(sline)
  153. if sline == 1 then return end
  154. for i=sline,#self.buffer do --Note: the sline is shifted
  155. self.buffer[i-1] = self.buffer[i]
  156. end
  157. table.remove(self.buffer,#self.buffer) --Remove the last line
  158. end
  159. return tb