SkyTheCoder

Passdrag Concept

May 14th, 2014
158
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. --# Passdrag
  3. Passdrag
  4.  
  5. = class() -- Looks odd as code, but nice if it crashes
  6.  
  7. local ellipseMesh = function(width, height, top, bottom, change) -- Function to create a(n) circle/ellipse mesh with a gradient
  8.     local pwidth, pheight, ptop, pbototom, pchange
  9.     pwidth = width or 128
  10.     if type(height) == "number" or height == nil then
  11.         pheight = height or width
  12.         ptop = top or color(255)
  13.         if type(bottom) == "userdata" then
  14.             pbottom = bottom or ptop
  15.             pchange = change or 1
  16.         else
  17.             pbottom = ptop
  18.             pchange = bottom or 1
  19.         end
  20.     else
  21.         pheight = width
  22.         ptop = height or color(255)
  23.         if type(top) == "userdata" then
  24.             pbottom  = top or ptop
  25.             pchange = bottom or 1
  26.         else
  27.             pbottom = ptop
  28.             pchange = top or 1
  29.         end
  30.     end
  31.    
  32.     pwidth, pheight = pwidth / 2, pheight / 2
  33.    
  34.    
  35.     local m = mesh()
  36.     local v = {}
  37.     local c = {}
  38.     local p = {}
  39.    
  40.     for d = 0, 360, pchange do
  41.         local r = math.rad(d)
  42.         table.insert(p, vec2(pwidth * math.sin(r), pheight * math.cos(r)))
  43.     end
  44.    
  45.     v = triangulate(p)
  46.    
  47.     m.vertices = v
  48.    
  49.     for k, v in ipairs(v) do
  50.         table.insert(c, ptop:mix(pbottom, v:normalize().y * 0.5 + 0.5))
  51.     end
  52.    
  53.     m.colors = c
  54.    
  55.     return m
  56. end
  57.  
  58. function Passdrag:init(x, y, size) -- Passdrag GUI & handler setup
  59.     self.rot = {a = 0}
  60.     self.tid = 0
  61.     self.size = size
  62.     self.x, self.y = x, y
  63.     self.ePos = vec2(0, size)
  64.     self.styles = {
  65.         Light = {
  66.             bg = color(255),
  67.             txt = color(200),
  68.             cFill = color(255),
  69.             cStroke = color(220),
  70.             cDark = color(210),
  71.             pWidth = 5,
  72.         },
  73.         Dark = {
  74.             bg = color(0),
  75.             txt = color(40),
  76.             cFill = color(30),
  77.             cStroke = color(25),
  78.             cDark = color(20),
  79.             pWidth = 5
  80.         },
  81.         Retro = {
  82.             bg = color(128, 96, 64, 255),
  83.             txt = color(64, 24, 16),
  84.             cFill = color(136, 102, 74, 255),
  85.             cStroke = color(74, 32, 24),
  86.             cDark = color(64, 24, 16),
  87.             pWidth = 3,
  88.         },
  89.         Nature = {
  90.             bg = color(191, 255, 191),
  91.             txt = color(31, 63, 31),
  92.             cFill = color(74, 136, 74),
  93.             cStroke = color(63, 127, 63),
  94.             cDark = color(48, 112, 48),
  95.             pWidth = 5,
  96.         },
  97.         Sky = {
  98.             bg = color(191, 223, 255),
  99.             txt = color(255),
  100.             cFill = color(95, 191, 255),
  101.             cStroke = color(240, 240),
  102.             cDark = color(74, 120, 255),
  103.             pWidth = 8,
  104.         },
  105.     }
  106.     self.oldStyles = self.styles
  107.     self.style = "Light"
  108.     self.darkness = {a = 0}
  109.     self:updateMesh()
  110.     self.sequence = ""
  111.     self.lastChar = ""
  112. end
  113.  
  114. function Passdrag:updateMesh() -- Update the gradiented mesh, not recommended for manual use
  115.     self.m = ellipseMesh(self.size / 3 - self.styles[self.style].pWidth, self.styles[self.style].cFill, self.styles[self.style].cDark, 10)
  116. end
  117.  
  118. function Passdrag:setStyle(x) -- Set style to x
  119.     self.style = x
  120.     self:updateMesh()
  121. end
  122.  
  123. function Passdrag:addStyle(x, y) -- Add style x with a preset of y
  124.     self.styles[x] = y
  125. end
  126.  
  127. function Passdrag:duplicateStyle(x, y) -- Make a new style y, with the presets of x
  128.     self.styles[y] = self.styles[x]
  129. end
  130.  
  131. function Passdrag:deleteStyle(x) -- Delete style x
  132.     self.styles[x] = nil
  133. end
  134.  
  135. function Passdrag:restoreStyle(x) -- Restore style (x or current) to its original preset
  136.     x = x or self.style
  137.     self.styles[x] = self.oldStyles[x]
  138. end
  139.  
  140. function Passdrag:restoreStyles() -- Restore all styles to their original presets
  141.     self.styles = self.oldStyles
  142. end
  143.  
  144. function Passdrag:addChar(x) -- Add character to current drag, not recommended for manual use
  145.     if x ~= self.lastChar then
  146.         self.sequence = self.sequence .. x
  147.         self.lastChar = x
  148.     end
  149. end
  150.  
  151. function Passdrag:resetSequence() -- Reset drag
  152.     self.sequence = ""
  153.     self.lastChar = ""
  154. end
  155.  
  156. function Passdrag:draw() -- Draw the GUI and update
  157.     for k, v in pairs(self.styles[self.style]) do
  158.         self["g" .. k] = v
  159.     end
  160.    
  161.     local checks = {"bg", "txt", "cFill", "cStroke", "cDark", "pWidth"}
  162.     for k, v in ipairs(checks) do
  163.         if self["s" .. v] ~= nil then
  164.             self.styles[style][v] = self["s" .. v]
  165.             self["s" .. v] = nil
  166.         end
  167.     end
  168.    
  169.     local deg = math.floor(math.abs((math.deg(self.rot.a) - 90) / 45) + 0.5)
  170.     if deg == 8 then
  171.         deg = 0
  172.     end
  173.     for i = 1, 3 do
  174.         if deg <= 5 then
  175.             deg = deg + 2
  176.             elseif deg >= 6 then
  177.             deg = deg - 6
  178.         end
  179.     end
  180.     self:addChar(tostring(deg + 1))
  181.    
  182.     local c = {}
  183.     for k, v in ipairs(self.m.vertices) do
  184.         table.insert(c, self.styles[self.style].cFill:mix(self.styles[self.style].cDark:mix(self.styles[self.style].cFill, self.darkness.a), v:normalize().y * 0.5 + 0.5))
  185.     end
  186.     self.m.colors = c
  187.    
  188.     pushMatrix()
  189.     pushStyle()
  190.     fill(self.styles[self.style].cFill)
  191.     stroke(self.styles[self.style].cStroke)
  192.     strokeWidth(self.styles[self.style].pWidth)
  193.     self.ePos.x, self.ePos.y = math.sin(-self.rot.a) * self.size / 2, math.cos(-self.rot.a) * self.size / 2
  194.     translate(self.x, self.y)
  195.     pushMatrix()
  196.     translate(self.ePos.x, self.ePos.y)
  197.     ellipse(0, 0, self.size / 3)
  198.     self.m:draw()
  199.     fill(0, 0)
  200.     ellipse(0, 0, self.size / 3)
  201.     popMatrix()
  202.     for i = 0, 7 do
  203.         pushMatrix()
  204.         rotate(i * (360 / 8))
  205.         line(self.size - self.size / 4, 0, self.size, 0)
  206.         popMatrix()
  207.     end
  208.     popStyle()
  209.     popMatrix()
  210. end
  211.  
  212. function Passdrag:touched(touch) -- Handles touches & animations on the GUI
  213.     if self.tid == 0 and touch.state == BEGAN and vec2(touch.x - self.x, touch.y - self.y):dist(self.ePos) < self.size / 3 then
  214.         self.tid = touch.id
  215.         if self.t ~= nil then
  216.             tween.stop(self.t)
  217.         end
  218.         if self.t2 ~= nil then
  219.             tween.stop(self.t2)
  220.         end
  221.         self.t = tween(0.45, self.darkness, {a = 1}, tween.easing.quadInOut)
  222.     end
  223.     if touch.id == self.tid and (touch.state == BEGAN or touch.state == MOVING) then
  224.         self.rot.a = math.atan2(touch.y - HEIGHT / 2, touch.x - WIDTH / 2) - math.pi / 2
  225.         local deg = math.floor(math.abs((math.deg(self.rot.a) - 90) / 45) + 0.5)
  226.         if deg == 8 then
  227.             deg = 0
  228.         end
  229.         for i = 1, 3 do
  230.             if deg <= 5 then
  231.                 deg = deg + 2
  232.                 elseif deg >= 6 then
  233.                 deg = deg - 6
  234.             end
  235.         end
  236.         self:addChar(tostring(deg + 1))
  237.     end
  238.     if touch.id == self.tid and (touch.state == ENDED or touch.state == CANCELLED) then
  239.         self.tid = 0
  240.         tween.stop(self.t)
  241.         self.t = tween(0.45, self.darkness, {a = 0}, tween.easing.quadInOut)
  242.         self.t2 = tween(0.45, self.rot, {a = math.rad(((math.floor(math.deg(self.rot.a) / 45 - 0.5) + 0.5) + 0.5) * 45)})
  243.     end
  244. end
  245.  
  246. --# Main
  247. -- Passdrag
  248.  
  249. function setup()
  250.     print()
  251.     pd = Passdrag(WIDTH / 2, HEIGHT / 2, 200)
  252.     styles = {"Light", "Dark", "Retro", "Nature", "Sky"}
  253.     parameter.integer("Style", 1, #styles, 1)
  254.     parameter.watch("styles[Style]")
  255.     parameter.watch("pd.sequence")
  256.     parameter.action("Save Passdrag", function()
  257.         savePassdrag()
  258.         output.clear()
  259.         print()
  260.         tween.delay(0.1, function()
  261.             output.clear()
  262.             print()
  263.             print("Passdrag saved")
  264.         end)
  265.     end)
  266.     parameter.watch("Saved_Passdrag")
  267.     parameter.watch("Passdrag_Matches_Saved")
  268. end
  269.  
  270. function draw()
  271.     pd:setStyle(styles[Style])
  272.    
  273.     background(pd.styles[pd.style].bg)
  274.    
  275.     Saved_Passdrag = readPassdrag()
  276.     Passdrag_Matches_Saved = pd.sequence == Saved_Passdrag
  277.    
  278.     pd:draw()
  279.    
  280.     font("HelveticaNeue-Light")
  281.     fontSize(48)
  282.     fill(pd.styles[pd.style].txt)
  283.     text("Passdrag", WIDTH / 2, HEIGHT - HEIGHT / 16)
  284.     fontSize(24)
  285.     text("Your drag: " .. pd.sequence, WIDTH / 2, HEIGHT - HEIGHT / 8)
  286.     text("Drag length: " .. pd.sequence:len(), WIDTH / 2, HEIGHT - HEIGHT / 6)
  287. end
  288.  
  289. function touched(touch)
  290.     pd:touched(touch)
  291. end
  292.  
  293. function savePassdrag()
  294.     local fileName = "passdrag.txt"
  295.     local file = os.getenv("HOME") .. "/Documents/" .. fileName
  296.     local wFd = io.open(file, "w")
  297.     wFd:write(pd.sequence)
  298.     wFd:close()
  299. end
  300.  
  301. function readPassdrag()
  302.     local fileName = "passdrag.txt"
  303.     local file = os.getenv("HOME") .. "/Documents/" .. fileName
  304.     local rFd = io.open(file, "r")
  305.     local v = ""
  306.     if rFd ~= nil then
  307.         for i in rFd:lines() do
  308.             v = v .. i
  309.         end
  310.     end
  311.     if rFd ~= nil then
  312.         rFd:close()
  313.     end
  314.    
  315.     return v
  316. end
RAW Paste Data