MattiasBuelens

CCGUI text

Jul 5th, 2012
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.29 KB | None | 0 0
  1. --[[
  2.  
  3.     ComputerCraft GUI
  4.     Text element
  5.  
  6. --]]
  7.  
  8. ccgui = ccgui or {}
  9.  
  10. local TextElement = common.newClass({
  11.     -- Text
  12.     text = "",
  13.     -- Text alignment
  14.     align = ccgui.Align.Left,
  15.     valign = ccgui.VAlign.Top,
  16.     -- Private: lines to draw
  17.     lines = nil,
  18.     lineCount = 0
  19. }, ccgui.Element)
  20. ccgui.TextElement = TextElement
  21.  
  22. function TextElement:init()
  23.     ccgui.Element.init(self)
  24.  
  25.     self:setText(self.text)
  26.  
  27.     self:on("paint", self.drawText, self)
  28. end
  29.  
  30. function TextElement:setText(text)
  31.     self.text = text or ""
  32.     self.lines = {}
  33.     --self:markRepaint()
  34. end
  35.  
  36. local function wrapLine(str, limit)
  37.     -- Wrap in words
  38.     str = string.gsub(str, "(%S+)",
  39.         function(word)
  40.             local length, lastBreak = #word, 0
  41.             while length - lastBreak > limit do
  42.                 lastBreak = lastBreak + limit
  43.                 word = string.sub(word, 1, lastBreak) .. "\n" .. string.sub(word, lastBreak+1)
  44.             end
  45.             return word
  46.         end
  47.     )
  48.     -- Wrap on word boundaries
  49.     local lastBreak = 1
  50.     return string.gsub(str, "(%s+)()(%S+)()",
  51.         function(spaces, start, word, finish)
  52.             if finish - lastBreak > limit then
  53.                 lastBreak = start
  54.                 return "\n"..word
  55.             end
  56.         end
  57.     )
  58. end
  59.  
  60. local function splitLines(str)
  61.     local t = {}
  62.     local function helper(line)
  63.         table.insert(t, line)
  64.         return ""
  65.     end
  66.     helper((string.gsub(str, "(.-)\n", helper)))
  67.     return t
  68. end
  69.  
  70. function TextElement.wordwrap(str, limit)
  71.     -- Clean leading spaces after newlines
  72.     --str = string.gsub(str, "%s*\n%s+", "\n")
  73.     -- Clean subsequent spaces
  74.     --str = string.gsub(str, "%s%s+", " ")
  75.     -- Wrap every single line
  76.     str = string.gsub(str, "[^\n]+",
  77.         function(line)
  78.             return wrapLine(line, limit)
  79.         end
  80.     )
  81.     return str
  82. end
  83.  
  84. function TextElement:calcSize(size)
  85.     -- Get inner bounding box
  86.     local bbox = self:inner(size)
  87.  
  88.     -- Wrap text to fit bounding box width
  89.     local text = self.wordwrap(self.text, bbox.w)
  90.  
  91.     -- Split in lines
  92.     self.lines = splitLines(text)
  93.  
  94.     -- Get longest line length
  95.     local nw = 0
  96.     for i,line in ipairs(self.lines) do
  97.         local len = #line
  98.         if(len > nw) then nw = len end
  99.     end
  100.  
  101.     -- Draw less lines if height limited
  102.     local nh = math.min(bbox.h, #self.lines)
  103.     self.lineCount = nh
  104.  
  105.     -- Get inner bounding box with new size
  106.     bbox = ccgui.newRectangle(bbox.x, bbox.y, nw, nh)
  107.     -- Use outer size box
  108.     self.size = self:outer(bbox)
  109. end
  110.  
  111. function TextElement:drawText()
  112.     -- Get inner bounding box
  113.     local bbox = self:inner(self.bbox)
  114.  
  115.     -- Vertical align
  116.     local firstLine, y = 1, bbox.y
  117.     local nLines, nLinesToPaint = #self.lines, self.lineCount
  118.     if self.valign == ccgui.VAlign.Center then
  119.         y = y + math.floor((bbox.h - nLinesToPaint)/2)
  120.         if nLines > nLinesToPaint then
  121.             firstLine = math.floor((nLines - nLinesToPaint)/2) + 1
  122.         end
  123.     elseif self.valign == ccgui.VAlign.Bottom then
  124.         y = y + bbox.h - nLinesToPaint
  125.         if nLines > nLinesToPaint then
  126.             firstLine = nLines - nLinesToPaint + 1
  127.         end
  128.     end
  129.  
  130.     local lastLine = firstLine + nLinesToPaint - 1
  131.     for i=firstLine,lastLine do
  132.         local line = self.lines[i]
  133.         -- Horizontal align
  134.         local x = bbox.x
  135.         local len = #(line)
  136.         if self.align == ccgui.Align.Center then
  137.             x = x + math.floor((bbox.w - len)/2)
  138.         elseif self.align == ccgui.Align.Right then
  139.             x = x + bbox.w - len
  140.         end
  141.         -- Write text
  142.         self:draw(x, y, line, self.foreground, self.background, bbox)
  143.         y = y + 1
  144.     end
  145. end
Advertisement
Add Comment
Please, Sign In to add comment