MattiasBuelens

CCGUI slider

Dec 20th, 2012
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.44 KB | None | 0 0
  1. --[[
  2.  
  3.     ComputerCraft GUI
  4.     Slider
  5.  
  6. --]]
  7.  
  8. ccgui = ccgui or {}
  9.  
  10. local ArrowButton = common.newClass({
  11.     border = ccgui.newBorder(0),
  12.     padding = ccgui.newMargins(0)
  13. }, ccgui.Button)
  14.  
  15. local Bar = common.newClass({
  16.     -- Orientation
  17.     horizontal      = false,
  18.     -- Dragging
  19.     dragStartPos    = nil,
  20.     dragStartValue  = nil
  21. }, ccgui.Element)
  22.  
  23. function Bar:init()
  24.     ccgui.Element.init(self)
  25.  
  26.     self:on("beforepaint", self.barLayout, self)
  27.     self:on("paint", self.barPaint, self)
  28.  
  29.     self:on("mouse_click", self.dragStart, self)
  30.     self:on("mouse_drag", self.dragging, self)
  31. end
  32.  
  33. function Bar:getBounds()
  34.     assert(self.parent.bbox ~= nil, "slider not positioned")
  35.     return self:inner(self.parent.bbox)
  36. end
  37.  
  38. -- Get the available space for the bar
  39. function Bar:getScreenRange()
  40.     local bbox = self:getBounds()
  41.     if self.horizontal then
  42.         return bbox.w-1
  43.     else
  44.         return bbox.h-1
  45.     end
  46. end
  47.  
  48. -- Convert the given scroll value to a screen value
  49. function Bar:toScreen(x)
  50.     return x * self:getScreenRange() / self.parent:getRange()
  51. end
  52.  
  53. -- Convert the given screen value to a scroll value
  54. function Bar:fromScreen(x)
  55.     return x * self.parent:getRange() / self:getScreenRange()
  56. end
  57.  
  58. -- Get the line representing the bar
  59. function Bar:getBarLine()
  60.     local bbox = self:getBounds()
  61.  
  62.     -- Get value details
  63.     local value, spanValue, maxValue = self.parent:getValue(), self.parent:getSpan(), self.parent:getMaximum()
  64.  
  65.     -- Get screen values
  66.     local start = self:toScreen(value)
  67.     local stop = self:toScreen(math.min(value + spanValue, maxValue))
  68.  
  69.     -- Get start and end positions
  70.     local startPos, stopPos
  71.     if self.horizontal then
  72.         startPos = vector.new(math.floor(start), 0)
  73.         stopPos = vector.new(math.floor(stop), 0)
  74.     else
  75.         startPos = vector.new(0, math.floor(start))
  76.         stopPos = vector.new(0, math.floor(stop))
  77.     end
  78.  
  79.     -- Create line
  80.     return ccgui.newLine(bbox:tl() + startPos, bbox:tl() + stopPos)
  81. end
  82.  
  83. -- Get the bounding rectangle of the bar
  84. function Bar:getBarRect()
  85.     local line = self:getBarLine()
  86.     if self.horizontal then
  87.         return ccgui.newRectangle(line.start, line:length(), 1)
  88.     else
  89.         return ccgui.newRectangle(line.start, 1, line:length())
  90.     end
  91. end
  92.  
  93. function Bar:barLayout()
  94.     self.bbox = self:getBounds()
  95. end
  96.  
  97. -- Draw the bar
  98. function Bar:barPaint()
  99.     -- Draw a line
  100.     self:drawLine(self:getBarLine(), self.foreground)
  101. end
  102.  
  103. -- Start dragging on mouse click on bar
  104. function Bar:dragStart(button, x, y)
  105.     if button == 1 and self.isVisible and self:getBarRect():contains(x, y) then
  106.         -- Store starting position
  107.         self.dragStartPos = vector.new(x, y)
  108.         self.dragStartValue = self.parent:getValue()
  109.     else
  110.         -- Stop dragging
  111.         self.dragStartPos = nil
  112.         self.dragStartValue = nil
  113.     end
  114. end
  115.  
  116. -- Adjust the scroll position while dragging
  117. function Bar:dragging(button, x, y)
  118.     if button == 1 and self.dragStartPos ~= nil then
  119.         -- Get drag delta
  120.         local current = vector.new(x, y)
  121.         local deltaPos = current - self.dragStartPos
  122.         local delta
  123.         if self.horizontal then
  124.             delta = self:fromScreen(deltaPos.x)
  125.         else
  126.             delta = self:fromScreen(deltaPos.y)
  127.         end
  128.         -- Add delta to starting value
  129.         self.parent:setValue(self.dragStartValue + math.floor(delta))
  130.     end
  131. end
  132.  
  133. local Slider = common.newClass({
  134.     -- Arrow buttons
  135.     showArrows      = true,
  136.     arrowLabels     = { "-", "+" },
  137.     -- Colors
  138.     colorForeground = colours.grey,
  139.     colorBar        = colours.grey,
  140.     colorButton     = colours.lightGrey,
  141.     -- Children
  142.     prevArrow       = nil,
  143.     nextArrow       = nil,
  144.     bar             = nil
  145. }, ccgui.FlowContainer)
  146. ccgui.Slider = Slider
  147.  
  148. function Slider:init()
  149.     ccgui.FlowContainer.init(self)
  150.  
  151.     -- Orientation
  152.     self.horizontal = not not self.horizontal
  153.  
  154.     -- Slider bar
  155.     self.bar = Bar:new({
  156.         parent      = self,
  157.         horizontal  = self.horizontal,
  158.         stretch     = true,
  159.         foreground  = self.colorBar,
  160.         background  = self.background
  161.     })
  162.  
  163.     -- Arrow buttons
  164.     self.showArrows = not not self.showArrows
  165.     if self.showArrows then
  166.         self.prevArrow = ArrowButton:new({
  167.             parent      = self,
  168.             text        = self.arrowLabels[1],
  169.             foreground  = self.colorForeground,
  170.             background  = self.colorButton
  171.         })
  172.         self.prevArrow:on("buttonpress", self.prevStep, self)
  173.         self.nextArrow = ArrowButton:new({
  174.             parent      = self,
  175.             text        = self.arrowLabels[2],
  176.             foreground  = self.colorForeground,
  177.             background  = self.colorButton
  178.         })
  179.         self.nextArrow:on("buttonpress", self.nextStep, self)
  180.         self:add(self.prevArrow, self.bar, self.nextArrow)
  181.     else
  182.         self:add(self.bar)
  183.     end
  184. end
  185.  
  186. function Slider:getValue()
  187.     error("Slider:getValue() not implemented")
  188. end
  189.  
  190. function Slider:rawSetValue(newValue)
  191.     error("Slider:rawSetValue() not implemented")
  192. end
  193.  
  194. function Slider:getStep()
  195.     error("Slider:getStep() not implemented")
  196. end
  197.  
  198. function Slider:getSpan()
  199.     error("Slider:getSpan() not implemented")
  200. end
  201.  
  202. function Slider:getMinimum()
  203.     error("Slider:getMinimum() not implemented")
  204. end
  205.  
  206. function Slider:getMaximum()
  207.     error("Slider:getMaximum() not implemented")
  208. end
  209.  
  210. function Slider:getRange()
  211.     return self:getMaximum() - self:getMinimum()
  212. end
  213.  
  214. function Slider:setValue(newValue)
  215.     self:rawSetValue(self:normalizeValue(newValue))
  216. end
  217.  
  218. function Slider:addValue(delta)
  219.     self:setValue(self:getValue() + delta)
  220. end
  221.  
  222. function Slider:normalizeValue(value)
  223.     value = math.max(value, self:getMinimum())
  224.     value = math.min(value, self:getMaximum() - self:getSpan())
  225.     return value
  226. end
  227.  
  228. function Slider:prevStep()
  229.     self:addValue(-self:getStep())
  230. end
  231.  
  232. function Slider:nextStep()
  233.     self:addValue(self:getStep())
  234. end
Advertisement
Add Comment
Please, Sign In to add comment