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 = '1.0'
-- Shape Numbers Explorer
-- Steve Arnold August 31 2011

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

    local screen = platform.window


W = screen:width()
H = screen:height()
num = 5 
tabnum = 0
types = 1
shw = 3

 timer.start(4)

function on.timer()
    H=screen:height() 
    W=screen:width()    

   screen:invalidate()
end
   

function on.resize()
    W = platform.window:width()
    H = platform.window:height()

    Square1 = Square(W - W/10, H/3, W/20)
    Rectangle1 = Rectangle(W - W/10, H/2, W/15, W/20)
    Triangle1 = Triangle(W - W/10, 2*H/3 + W/20, W/20)
    

   vslider = Slider(0.05*W, 0.8*H, 0.05*W, 0.675*H, 0.05*W, 0.2*H, 0.05*W, 0, 1, 20, 1, "n", Color.blue)
    hslider = Slider(0.15*W, 0.925*H, 0.15*W, 0.925*H, 0.8*W, 0.925*H, 0.05*W, 1, 1, 20, 1, "◀ Build ▶", Color.blue)
 
    resetbutton = Button(0.8*W, 0.025*H, W/5, H/10, Color.blue, "reset", false)

        vslider.value = 5
        hslider.value = 1
        num = 5 
        tabnum = 0
        types = 1
        shw = 3
 
    platform.window:invalidate()
end

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

Circle = class()

function Circle:init(x, y, width, height)

    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.radius = height/2
    self.colour = Color.blue
    self.selected = false
end


function Circle:contains(x, y)

    local r = self.radius
    local d = math.sqrt((self.x - x)^2 + (self.y - y)^2)
    return d <= r
end


function Circle:paint(gc)

    local cx = self.x - self.radius
    local cy = self.y - self.radius
    local diameter = 2*self.radius
    gc:setColorRGB(unpack(self.colour))
    gc:fillArc(cx, cy, diameter, diameter, 0, 360)
    if self.selected then
        gc:setPen("medium","smooth")
        gc:setColorRGB(0, 0, 0)
        gc:drawArc(cx - diameter/2, cy - diameter/2, 2*diameter, 2*diameter, 0, 360)
    end 
    platform.window:invalidate()
end

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

Square = class()

function Square:init(x, y, size)

    self.x = x
    self.y = y
    self.width = size
    self.colour = Color.green
    self.selected = false
end


function Square:contains(x, y)
    local w = self.width
    return x >= self.x and x <= self.x + w and
           y >= self.y and y <= self.y + w
end


function Square:paint(gc)
    local cx = self.x
    local cy = self.y
    local size = self.width
    gc:setColorRGB(unpack(self.colour))
    gc:fillRect(cx, cy, size, size)
    if self.selected then
        gc:setPen("medium","smooth")
        gc:setColorRGB(255, 0, 0)
        gc:fillRect(cx, cy, size, size)
        gc:setColorRGB(0, 0, 0)
        gc:drawRect(cx, cy, size, size)
    end 
    platform.window:invalidate()
end


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

Rectangle = class()

function Rectangle:init(x, y, width, height)

    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.colour = Color.blue
    self.selected = false
end


function Rectangle:contains(x, y)
    local w = self.width
    local h = self.height
    return x >= self.x and x <= self.x + w and
           y >= self.y and y <= self.y + h
end


function Rectangle:paint(gc)
    local cx = self.x
    local cy = self.y
    local width = self.width
    local height = self.height
    gc:setColorRGB(unpack(self.colour))
    gc:fillRect(cx, cy, width, height)
    if self.selected then
        gc:setPen("medium","smooth")
        gc:setColorRGB(255, 0, 0)
        gc:fillRect(cx, cy, width, height)
        gc:setColorRGB(0, 0, 0)
        gc:drawRect(cx, cy, width, height)
    end 
    platform.window:invalidate()
end

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

Triangle = class()

function Triangle:init(x, y, size)

    self.x = x
    self.y = y
    self.width = size
    self.colour = Color.red
    self.selected = false
end


function Triangle:contains(x, y)

    local w = self.width
    return x >= self.x and x <= self.x + w and
           y >= self.y - w and y <= self.y
end


function Triangle:paint(gc)
    local cx = self.x
    local cy = self.y
    local size = self.width
    local vertices = {cx, cy, cx + size, cy, cx + size/2, cy - size, cx, cy}
    gc:setColorRGB(unpack(self.colour))
    gc:fillPolygon(vertices)
    if self.selected then
        gc:setPen("medium","smooth")
        --gc:setColorRGB(255, 0, 0)
        --gc:fillPolygon(vertices)
        gc:setColorRGB(unpack(Color.black))
        gc:drawPolyLine(vertices)
    end 
    platform.window: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/4 
    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 

    if self.orient == 1 then 
         self.step = (self.ex - self.sx)/(self.range) 
    else 
         self.step = (self.sy - self.ey)/(self.range) 
    end 


    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, 2 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(0, 0, 0)    
    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(80, 80, 80)    
    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, 2 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(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 - width, y - radius/2, radius, radius, 0, 360) 
    gc:setColorRGB(unpack(Color.black))    
    gc:drawArc(x - width, y - radius/2, radius, radius, 0, 360) 
    
    end 
    
    end 
   
    
    end 
    
    return self.value 

end 




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 resetbutton:contains(x, y) then
	    resetbutton.selected = true
	    screen:invalidate()
	end

    if Square1:contains(x, y) then
	    Square1.selected = true
	    screen:invalidate()
	end

    if Triangle1:contains(x, y) then
	    Triangle1.selected = true
	    screen:invalidate()
	end

    if Rectangle1:contains(x, y) then
	    Rectangle1.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.2*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.9*h and not resetbutton:contains(x, y) then
            on.arrowDown()
        elseif vslider.y > y then
            on.arrowUp()
        end        
    end

	if hslider.selected then
        hslider.selected = false
	    screen:invalidate()	    
	end

	if vslider.selected then
        vslider.selected = false
	    screen:invalidate()	    
	end


    if resetbutton.selected then
        on.resize(gc)
	    resetbutton.selected = false
	    screen:invalidate()
	end

    if Triangle1.selected then
        types = 3
        Triangle1.selected = false
    elseif Rectangle1.selected then
        types = 2
        Rectangle1.selected = false
    elseif Square1.selected then
        types = 1
        Square1.selected = false
    end

		screen:invalidate()
end

function on.mouseMove(x,y)


	if vslider.selected == true  then
	
	  if y >= vslider.ey and y <= vslider.sy then
	       vslider.y = y
	       num = vslider.value
	  end
	  
      screen:invalidate()

	end

	if hslider.selected == true  then
	
	  if x >= hslider.sx and x <= hslider.ex then
	       hslider.x = x
	       tabnum = hslider.value
	  end
      screen:invalidate()

	end

    screen:invalidate()
end


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

-- Grab keyboard entry to build the variable answer.


function on.arrowUp()
    if  num < 18 then
        num = num + 1
    vslider.y = vslider.y - vslider.step
    end
    screen:invalidate()
end
    
function on.arrowDown() 
    if num > 1 then
        num = num - 1
    vslider.y = vslider.y + vslider.step
    end
    screen:invalidate()
end

function on.arrowLeft()
   if tabnum < num - 1 then
        tabnum = tabnum + 1
     hslider.x = hslider.x - hslider.step
    end
    screen:invalidate()

end

function on.arrowRight() 
    if tabnum < num - 1 then
        tabnum = tabnum + 1
   hslider.x = hslider.x + hslider.step
   end
    screen:invalidate()

end

   

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


function on.enterKey()
    if types < 4 then
        types = types % 3 + 1
    else
        types = 3
    end    
    platform.window:invalidate()
end


function on.tabKey()
    if types < 4 then
        types = types % 3 + 1
    else
        types = 3
    end  

    platform.window:invalidate()
end


function on.escapeKey()

         on.resize()
--    shw = (shw + 1) % 4
    platform.window:invalidate()
            
end

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

function counter(tabnum, gc)
    local w = platform.window:width()
    local h = platform.window:height()
    local xval = math.floor(h/(num+4))
    local yval = math.floor(h/(num+4))
    local x = w/2 - (num)*(xval)/2
    local y = h/2 - (num)*(yval)/2

    gc:setPen("thin", "smooth")     
    if types == 1 then
        if tabnum < 1 then
            gc:setColorRGB(20, 20, 138)
            gc:fillArc(x, y, xval, yval, 0, 360)
        else
 
            for k = 0, tabnum do
                for m = 0, tabnum do
                gc:setColorRGB((20+25*k) % 255, (20+25*k) % 255, (138-25*k) % 255)
                gc:fillArc(x + (xval)*(m), y + (yval)*(k), xval, yval, 0, 360)
end
            end
        end
    elseif types == 2 then
        
        if tabnum < 1 then
            gc:setColorRGB(20, 20, 138)
            gc:fillArc(x, y, xval, yval, 0, 360)
            gc:fillArc(x + xval, y, xval, yval, 0, 360)
        else
 
            for k = 1, tabnum + 1 do
                for m = 0, tabnum + 1 do
                 gc:setColorRGB((20+25*k) % 255, (20+25*k) % 255, (138-25*k) % 255)
                 gc:fillArc(x + (xval)*(m), y + yval*(k-1), xval, yval, 0, 360)
                end
            end
        end


    else
        for k = 0, tabnum do
            gc:setColorRGB((20+25*k) % 255, (20+25*k) % 255, (138-25*k) % 255)
            for m = k, tabnum do
                gc:fillArc(x + (xval)*(m), y + yval*(k), xval, yval, 0, 360)
            end
        end
    end
    platform.window:invalidate()
end

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

function drawArray(number, x, y, length, height, gc)
    w = platform.window:width()
    h = platform.window:height()
    
    if types == 1 then
        if shw ==1 then
            gc:drawRect(x, y, (length)*(number+1) - length, height*(number))
            for k = 1, number do
                for m = 1, number do
                    gc:drawArc(x + (length)*(m-1), y + (height)*(k-1), length, height, 0, 360)
                end
            end
        elseif shw == 2 then
       
            for k = 0, number do
                for m = 0, number do
         
                    gc:drawLine(x, y + (height)*(m), x + (length)*(number), y + (height)*(m))
                    gc:drawLine(x + (length)*(k), y, x + (length)*(k), y + height*(number))
         
                end
            end    
       
        else
            for k = 1, number do
                for m = 1, number do
                    gc:drawArc(x + (length)*(m-1), y + (height)*(k-1), length, height, 0, 360)
                end
            end
        end
    elseif types == 2 then
        if shw ==1 then
            gc:drawRect(x, y, length*(number+1), height*(number))    
            for k = 1, number do
                for m = 0, number do
                    gc:drawArc(x + (length)*(m), y + height*(k-1), length, height, 0, 360)
                end
            end
        elseif shw == 2 then
            for k = 0, number+1 do
                for m = 0, number do
         
                    gc:drawLine(x, y + (height)*(m), x + (length)*(number+1), y + (height)*(m))
                    gc:drawLine(x + (length)*(k), y, x + (length)*(k), y + height*(number))
         
                end
            end    

        else
            for k = 2, number+1 do
                for m = 1, number+1 do
                    gc:drawArc(x + (length)*(m-1), y + height*(k-2), length, height, 0, 360)
                end
            end
        end
    else

        if shw == 1 then
            gc:drawPolyLine({x - 0.7*length, y, x + (number)*length, y, x + (number)*length, y + (number+1)*height - height/5, x - 0.7*length, y})
            for k = 1, number do
                for m = k, number do
                    gc:drawArc(x + length*(m-1), y + height*(k-1), length, height, 0, 360)
                end
            end
        elseif shw == 2 then
       
            for k = 1, number do
                for m = k, number do
                 
                    gc:drawLine(x, y, x + (length)*(number+1) - length, y )         
                    gc:drawLine(x + length*(m-1), y + (height)*(m), x + (length)*(number), y + (height)*(m))
                    gc:drawLine(x + (length)*(m-1), y, x + (length)*(m-1), y + height*(m))
                    gc:drawLine(x + (length)*(number), y, x + (length)*(number), y + height*(number))
          
                end
            end    
       
        else
            for k = 1, number do
                for m = k, number do
                    gc:drawArc(x + length*(m-1), y + height*(k-1), length, height, 0, 360)
                end
            end
        end
     end
    platform.window:invalidate()
end

-------------------------------------------------------------------------------------
 
function on.paint(gc)
    h = screen:height()
    w = screen:width()
    
    
        local fontSize = math.floor(w/32)
   	    local fontSize = math.floor(fontSize)
	    local fontSize = fontSize > 6 and fontSize or 7
        gc:setFont("sansserif", "r", fontSize)

        gc:setColorRGB(240, 240, 240)
        gc:fillRect(0,0,w,h)


    if tabnum > -1 and tabnum < num then
        counter(tabnum, gc)
    end
     
    xval = math.floor(h/(num+4))
    yval = math.floor(h/(num+4))
    x = w/2 - (num)*(xval)/2
    y = h/2 - (num)*(yval)/2

    gc:setColorRGB(165,42,42)
    gc:setPen("thin", "smooth")
    
    drawArray(num, x, y, xval, yval, gc)

    gc:setFont("sansserif", "b", fontSize)
    gc:setColorRGB(20, 20, 138)
    
    if types == 1 then
        str1 = "Square Numbers"
        str2 = num.." × "..num.." = "..num^2
        str3 = "1"
        for k = 2, tabnum + 1 do
             str3 = str3.."+"..2*k - 1
        end
    elseif types == 2 then
        str1 = "Rectangular Numbers"
        str2 = num.." × "..(num+1).." = "..num*(num+1)
        str3 = "2"
        for k = 2, tabnum + 1 do
            str3 = str3.."+"..2*k
        end
    else
        str1 = "Triangular Numbers"
        str2 = "("..num.." × "..(num+1)..")/2 = "..num*(num+1)/2
        str3 = "1"
        for k = 2, tabnum + 1 do
              str3 = str3.."+"..k
        end

    end


    if shw == 3 or shw == 1 then 
        strwidth = gc:getStringWidth(str1..": "..str2)
        gc:drawString(str1..": "..str2, 0.05*w , h/15, "middle") 
        
        
        local fontSize = math.floor(w/50 + 0.5)
   	    local fontSize = math.floor(fontSize)
	    local fontSize = fontSize > 6 and fontSize or 7
        gc:setFont("sansserif", "r", fontSize)
       gc:setColorRGB(20, 20, 138)   
        strwidth = gc:getStringWidth(str3)
        gc:drawString(str3, (w - strwidth)/2 , h, "bottom")
    end
    
       local fontSize = math.floor(w/50 + 0.5)
   	    local fontSize = math.floor(fontSize)
	    local fontSize = fontSize > 6 and fontSize or 7
        gc:setFont("sansserif", "i", fontSize)
    gc:setColorRGB(0, 0, 255)



     gc:drawString(" ▲", 9*w/10,8.25*h/10)
       local sw = gc:getStringWidth("Choose") 
    gc:drawString("Choose", w - sw - 5,9*h/10)
       local sw = gc:getStringWidth("Type") 
    
    gc:drawString("Type", w - sw - 5,9.5*h/10)
   
   Square1:paint(gc)
   Rectangle1:paint(gc)
   Triangle1:paint(gc)
 
    hslider:paint(gc)
    vslider:paint(gc)
    resetbutton:paint(gc)
end