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 



		---------------------------------------------------------------------------