Home ← TI-Nspire Authoring ← Lua Scripting HQ ← Lua and JavaScript
Todo: - Image support - Font size support - Physics support - Toolpallete support - Clipboard - D2Editor - coroutine (possibly not possible) - string functions - keyboard improvements
platform.apilevel = '2.0' -- Steve Arnold local W local H local screen = platform.window local width = 6 local height = 2 local colornum = 1 Color = { red = {255, 0, 0}, orange = {255, 165, 0}, yellow = {255, 255, 0}, green = {0, 255, 0}, realblue = {0, 0, 255}, white = {255, 255, 255}, black = {0, 0, 0}, paleblue = {0, 175, 235}, navy = {20, 20, 138}, maroon = {170, 50, 50}, gray = {120, 120, 120}, lightgray = {240, 240, 240}, bluesteel = {0, 175, 235}, salmon1 = {235, 230, 230}, salmon = {220, 220, 250}, blue = {0, 155, 235} } buttoncolors = { Color.red, Color.maroon, Color.orange, Color.yellow, Color.green, Color.paleblue, Color.bluesteel, Color.blue, Color.realblue, Color.navy, Color.salmon1, Color.lightgray, Color.gray, Color.black } function on.paint(gc) screen = platform.window W = screen:width() H = screen:height() gc:setColorRGB(220, 220, 200) gc:fillRect(0, 0, W, H) fontSize = math.floor(W/35 + 0.5) fontSize = math.floor(fontSize) fontSize = fontSize > 6 and fontSize or 7 gc:setFont("sansserif", "i", fontSize) gc:setColorRGB(unpack(Color.gray)) local answer = "This one does not use images" local sw0 = gc:getStringWidth(answer) gc:drawString(answer, 0.95*W - sw0, 0.1*H) hslider:paint(gc) vslider:paint(gc) cslider:paint(gc) mainbutton:paint(gc) end function on.resize(gc) W = screen:width() H = screen:height() width = 6 height = 2 colornum = 1 vslider = Slider(0.975*W, 0.8*H, 0.975*W, 0.65*H, 0.975*W, 0.2*H, 0.025*W, 0, 1, 4, 10, "height", buttoncolors[colornum]) hslider = Slider(0.2*W, 0.95*H, 0.5325*W, 0.95*H, 0.8*W, 0.95*H, 0.025*W, 1, 1, 9, 10, "width", buttoncolors[colornum]) cslider = Slider(0.05*W, 0.8*H, 0.05*W, 0.8*H, 0.05*W, 0.2*H, 0.025*W, 0, 1, 13, 1, "color", buttoncolors[colornum]) mainbutton = Button(W/2 - width*W/20, H/2 - height*H/20, width*W/10, height*H/10, buttoncolors[colornum], "RESET", false) screen:invalidate() end --------------------------------------------------------------------------- -- The Button Button = class() function round(input) return math.floor(input + 0.5) end function Button:init(x, y, width, height, color, label, selected) self.x = x self.y = y self.width = width self.height= height self.color = color self.label = label self.selected = false end function Button:contains(x, y) local sw = self.width or self.height local sh = self.height or self.width return x >= self.x and x <= self.x + sw and y >= self.y and y <= self.y + sh end function Button:paint(gc) local x = self.x local y = self.y local width = self.width local height = self.height local label = self.label gc:setColorRGB(unpack(self.color)) gc:setPen("thin", "smooth") local curve = 0.25*height gc:fillRect(round(x + curve), round(y), round(width - 2*curve), round(height)) gc:fillRect(round(x), round(y + curve), round(width), round(height - 2*curve)) gc:fillArc(round(x), round(y), round(2*curve), round(2*curve), 90, 90) gc:fillArc(round(x + width - 2*curve), round(y), round(2*curve), round(2*curve), 0, 90) gc:fillArc(round(x + width - 2*curve), round(y + height - 2*curve), round(2*curve), round(2*curve), 270, 90) gc:fillArc(round(x), round(y + height - 2*curve), round(2*curve), round(2*curve), 180, 90) gc:fillRect(round(x + curve), round(y), round(width - 2*curve), round(height)) gc:fillRect(round(x), round(y + curve), round(width), round(height - 2*curve)) gc:drawArc(round(x), round(y), round(2*curve), round(2*curve), 90, 90) gc:drawArc(round(x + width - 2*curve), round(y), round(2*curve), round(2*curve), 0, 90) gc:drawArc(round(x + width - 2*curve), round(y + height - 2*curve), round(2*curve), round(2*curve), 270, 90) gc:drawArc(round(x), round(y + height - 2*curve), round(2*curve), round(2*curve), 180, 90) gc:drawRect(round(x + curve), round(y), round(width - 2*curve), round(height)) gc:drawRect(round(x), round(y + curve), round(width), round(height - 2*curve)) gc:drawRect(round(x + curve), round(y), round(width - 2*curve), round(height)) gc:drawRect(round(x), round(y + curve), round(width), round(height - 2*curve)) gc:drawLine(round(x + curve), round(y), round(x + width - curve), round(y)) gc:drawLine(round(x + width), round(y + curve), round(x + width), round(y - curve + height)) gc:drawLine(round(x + width - curve), round(y + height), round(x + curve), round(y + height)) gc:drawLine(round(x), round(y + height - curve), round(x), round(y + curve)) gc:drawArc(round(x), round(y), round(2*curve), round(2*curve), 90, 90) gc:drawArc(round(x + width - 2*curve), round(y), round(2*curve), round(2*curve), 0, 90) gc:drawArc(round(x + width - 2*curve), round(y + height - 2*curve), round(2*curve), round(2*curve), 270, 90) gc:drawArc(round(x), round(y + height - 2*curve), round(2*curve), round(2*curve), 180, 90) local fontSize = math.floor(height/5) local fontSize = fontSize local fontSize = fontSize >= 7 and fontSize or 7 local fontSize = fontSize <= 24 and fontSize or 24 gc:setFont("sansserif","b",fontSize) if self.selected then gc:setColorRGB(unpack(Color.red)) else gc:setColorRGB(unpack(Color.white)) end local sw = gc:getStringWidth(label) local sh = gc:getStringHeight(label) gc:drawString(label, round(x + width/2 - sw/2), round(y + height*0.4), "middle") end --------------------------------------------------------------------------- -- Sliders Slider = class() function Slider:init(sx, sy, x, y, ex, ey, radius, height, startvalue, range, units, label, color) self.sx = sx self.sy = sy self.x = x self.y = y self.ex = ex self.ey = ey self.radius = radius self.width = self.radius/2 self.height = height self.startvalue = startvalue self.range = range self.units = units self.label = label self.color = color self.selected = false self.value = Xval self.orient = (ex - sx == 0) and 0 or 1 -- Vertical default self.textorient = 1 if self.orient == 0 and sx < 0.1*W then self.textorient = -1 end if self.orient == 1 and H - sy < 0.1*H then self.textorient = -1 end end function Slider:contains(x, y) local r = self.radius local d = math.sqrt((self.x - x)^2 + (self.y - y)^2) return d <= r end function Slider:paint(gc) local sx = self.sx local sy = self.sy local x = self.x local y = self.y local ex = self.ex local ey = self.ey local width = self.width local height = self.height local radius = self.radius local orient = self.orient local text = self.textorient if orient == 0 then self.value = math.floor(self.units*(self.range*(sy - y)/(sy - ey) + self.startvalue) + 0.5)/self.units gc:setColorRGB(unpack(Color.gray)) local fontSize = math.floor(W/60+0.5) local fontSize = fontSize > 6 and fontSize or 7 gc:setFont("sansserif", "b", fontSize) local sw = gc:getStringWidth(self.label.."="..self.value) if text == 1 then gc:drawString(self.label.."="..self.value, sx - 1.3*sw, y, "middle") else gc:drawString(self.label.."="..self.value, sx + 0.275*sw, y, "middle") end gc:setColorRGB(unpack(Color.gray)) for k = self.startvalue, self.startvalue + self.range, 1 do local fontSize = math.floor(W/100+0.5) local fontSize = fontSize > 6 and fontSize or 7 gc:setFont("sansserif", "r", fontSize) local sw = gc:getStringWidth(k) if text == 1 then gc:drawString("-", sx - width*1.75, sy - (k - self.startvalue)*(sy - ey)/self.range, "middle") else gc:drawString("-", sx + width*0.75, sy - (k - self.startvalue)*(sy - ey)/self.range, "middle") end gc:setPen("thin", "smooth") gc:setColorRGB(250, 250, 250) gc:fillPolygon({sx - width/2, sy, sx - width/2, ey, sx + width/2, ey, sx + width/2, sy, sx - width/2, sy }) gc:fillArc(sx - width/2, ey - width/2, width, width, 0, 180) gc:setColorRGB(unpack(self.color)) gc:fillPolygon({sx - width/2, sy, sx - width/2, y, sx + width/2, y, sx + width/2, sy, sx - width/2, sy }) gc:fillArc(sx - width/2, sy - width/2, width, width, 180, 180) gc:setColorRGB(unpack(Color.gray)) gc:drawLine(sx - width/2, sy, sx - width/2, ey) gc:drawLine(sx + width*0.5, sy, sx + width*0.5, ey) gc:drawArc(sx - width/2, sy - width/2, width, width, 180, 180) gc:drawArc(sx - width/2, ey - width/2, width, width, 0, 180) end if self.selected then gc:setPen("medium", "smooth") gc:setColorRGB(unpack(self.color)) gc:fillArc(x - radius, y - radius, 2*radius, 2*radius, 0, 360) gc:setColorRGB(unpack(Color.black)) gc:drawArc(x - radius, y - radius, 2*radius, 2*radius, 0, 360) else gc:setColorRGB(unpack(self.color)) gc:fillArc(x - radius/2, y - radius/2, radius, radius, 0, 360) gc:setColorRGB(unpack(Color.black)) gc:drawArc(x - radius/2, y - radius/2, radius, radius, 0, 360) end else gc:setColorRGB(unpack(Color.gray)) self.value = math.floor(self.units*(self.range*(sx - x)/(sx - ex) + self.startvalue) + 0.5)/self.units local fontSize = math.floor(W/60 + 0.5) local fontSize = fontSize > 6 and fontSize or 7 gc:setFont("sansserif", "r", fontSize) local str = self.label.." = "..self.value local sw = gc:getStringWidth(str) local sh = gc:getStringHeight(str) if text == 1 then gc:drawString(str, (sx + ex)/2 - sw/2, y + sh, "middle") else gc:drawString(str, (sx + ex)/2 - sw/2, y - sh, "middle") end for k = self.startvalue, self.startvalue + self.range do local fontSize = math.floor(W/100) local fontSize = fontSize > 6 and fontSize or 7 gc:setFont("sansserif", "r", fontSize) local sw = gc:getStringWidth("|") if text == 1 then gc:drawString("|", sx + (k - self.startvalue)*(ex - sx)/self.range - sw/2, sy + width*1.5, "middle") else gc:drawString("|", sx + (k - self.startvalue)*(ex - sx)/self.range - sw/2, sy - width*1.2, "middle") end gc:setPen("thin", "smooth") gc:setColorRGB(250, 250, 250) gc:fillPolygon({sx, sy - width/2, ex, ey - width/2, ex, ey + width/2, sx, sy + width/2, sx, sy - width/2 }) gc:fillArc(ex - width/2, ey - width/2, width, width*1, -90, 180) gc:setColorRGB(unpack(self.color)) gc:fillPolygon({sx, sy - width/2, x, sy - width/2, x, sy + width/2, sx, sy + width/2, sx, sy - width/2 }) gc:fillArc(sx - width*0.5, sy - width/2, width, width, 90, 180) gc:setColorRGB(unpack(Color.gray)) gc:drawLine(sx, sy - width/2, ex, ey - width/2) gc:drawLine(sx, sy + width*0.5, ex, ey + width*0.5) gc:drawArc(sx - width/2, sy - width/2, width, width*1, 90, 180) gc:drawArc(ex - width/2, ey - width/2, width, width*1, -90, 180) if self.selected then gc:setPen("medium", "smooth") gc:setColorRGB(unpack(Color.black)) gc:drawArc(x - radius, y - radius, 2*radius, 2*radius, 0, 360) gc:setColorRGB(unpack(self.color)) gc:fillArc(x - radius, y - radius, 2*radius, 2*radius, 0, 360) else gc:setColorRGB(unpack(self.color)) gc:fillArc(x - radius/2, y - radius/2, radius, radius, 0, 360) gc:setColorRGB(unpack(Color.black)) gc:drawArc(x - radius/2, y - radius/2, radius, radius, 0, 360) end end end return self.value end --------------------------------------------------------------------------- -- SECTION 3: Mouse controls function on.mouseDown(x,y) if hslider:contains(x, y) then hslider.selected = true screen:invalidate() end if vslider:contains(x, y) then vslider.selected = true screen:invalidate() end if cslider:contains(x, y) then cslider.selected = true screen:invalidate() end if mainbutton:contains(x, y) then mainbutton.selected = true screen:invalidate() end screen:invalidate() end function on.mouseUp(x,y) if math.abs(hslider.y - y) < 0.05*H then if hslider.x < x and x < 0.9*W and x > 0.1*W then on.arrowRight() elseif hslider.x > x then on.arrowLeft() end end if math.abs(vslider.x - x) < 0.05*W then if vslider.y < y and y > 0.2*H and y < 0.8*H then on.arrowDown() elseif vslider.y > y then on.arrowUp() end end if math.abs(cslider.x - x) < 0.05*W then if cslider.y < y and y > 0.2*H then cslider.y = cslider.y + cslider.range/2 colornum = cslider.value - 1 vslider.color = buttoncolors[colornum] cslider.color = buttoncolors[colornum] hslider.color = buttoncolors[colornum] mainbutton.color = buttoncolors[colornum] else cslider.y = cslider.y - cslider.range/2 colornum = cslider.value + 1 vslider.color = buttoncolors[colornum] cslider.color = buttoncolors[colornum] hslider.color = buttoncolors[colornum] mainbutton.color = buttoncolors[colornum] end screen:invalidate() end if hslider.selected then hslider.selected = false screen:invalidate() end if vslider.selected then vslider.selected = false screen:invalidate() end if cslider.selected then cslider.selected = false screen:invalidate() end if mainbutton.selected then on.resize(gc) mainbutton.selected = false screen:invalidate() end screen:invalidate() end function on.mouseMove(x,y) if cslider.selected == true then if y >= cslider.ey and y <= cslider.sy then cslider.y = y colornum = cslider.value vslider.color = buttoncolors[colornum] cslider.color = buttoncolors[colornum] hslider.color = buttoncolors[colornum] mainbutton.color = buttoncolors[colornum] end screen:invalidate() end if vslider.selected == true then if y >= vslider.ey and y <= vslider.sy then vslider.y = y height = vslider.value mainbutton.height = height*H/10 mainbutton.y = H/2 - mainbutton.height/2 end screen:invalidate() end if hslider.selected == true then if x >= hslider.sx and x <= hslider.ex then hslider.x = x width = hslider.value mainbutton.width = width*W/10 mainbutton.x = W/2 - mainbutton.width/2 end screen:invalidate() end screen:invalidate() end --------------------------------------------------------------------------- function on.escapeKey() on.resize() screen:invalidate() end function on.tabKey() -- choose = choose + 1 % 3 + 1 screen:invalidate() end function on.arrowUp() if vslider.y >= vslider.ey + vslider.units and vslider.y <= vslider.sy then vslider.y = vslider.y - vslider.range/2 height = vslider.value - 0.1 mainbutton.height = height*H/10 mainbutton.y = H/2 - mainbutton.height/2 end screen:invalidate() end function on.arrowDown() if vslider.y >= vslider.ey and vslider.y <= vslider.sy - vslider.units then vslider.y = vslider.y + vslider.units height = vslider.value + 0.1 mainbutton.height = height*H/10 mainbutton.y = H/2 - mainbutton.height/2 end screen:invalidate() end function on.arrowLeft() if hslider.x >= hslider.sx + hslider.units and hslider.x <= hslider.ex then hslider.x = hslider.x - hslider.units width = hslider.value mainbutton.width = width*W/10 mainbutton.x = W/2 - mainbutton.width/2 end screen:invalidate() end function on.arrowRight() if hslider.x >= hslider.sx and hslider.x <= hslider.ex - hslider.units then hslider.x = hslider.x + hslider.units width = hslider.value mainbutton.width = width*W/10 mainbutton.x = W/2 - mainbutton.width/2 end screen:invalidate() end ---------------------------------------------------------------------------