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
---------------------------------------------------------------------------