Screens Class

This here is a screens class, you can add elements to it as shown in the main. It draws things in its box, and it can be resized and moved seamlessly. It takes one controlElement that it will send touches to and will run the draw of: this control element should be used to control the other elements, like the main part of a main menu, or the main code for a game. You can set up multiple screens, tween their x values for transitions, etc. also, you needn’t handle touches any differently in any of the elements: the screen takes in touches and automatically converts the x and y values to the range (0,WIDTH),(0,HEIGHT) no matter what size the screen is

Screen = class()
function Screen:init(pos,controlElement, elements, scalefactor)
    self.scalefactor = scalefactor or 1
    self.size = vec2(WIDTH*(scalefactor or 1),HEIGHT*(scalefactor or 1))
    if controlElement and controlElement[1] then
        self.controlElement = controlElement[1](unpack(controlElement[2] or {}))
        elseif controlElement then
        self.controlElement = controlElement
    end
    self.elements = elements or {}
    self.pos = pos or vec2(0,0)
    self.x,self.y = self.pos.x,self.pos.y
    self.clipelements = true
    self.active,self.drawing = true,true
end

function Screen:draw()
    self.pos.x,self.pos.y = self.x,self.y
    if self.controlElement and self.active then self.controlElement:draw() end
    pushMatrix()
    pushStyle()
    scale(self.scalefactor)
    translate(self.pos.x*(1/self.scalefactor),self.pos.y*(1/self.scalefactor))
    clip(self.pos.x,self.pos.y, WIDTH*self.scalefactor,HEIGHT*self.scalefactor)
    if self.drawing then
        for a,b in pairs(self.elements) do
            if b[1] then
                b[1](unpack(b[2]))
                else
                b:draw()
            end
        end
    end
    popMatrix()
    popStyle()
end
function Screen:touched(t)
    if self.controlElement and self.active then
        local px = (t.x-self.pos.x*(1/self.scalefactor))/self.scalefactor
        local py = (t.y-self.pos.x*(1/self.scalefactor))/self.scalefactor
        if px>0 and px < WIDTH and py >0 and py < HEIGHT then
            self.controlElement:touched({x = px,y = py,id = t.id,state = t.state, tapCount = t.tapCount})
        end
    end
end

function Screen:move(vec2_move)
    self.pos = self.pos + vec2_move
    self.x,self.y = self.pos.x,self.pos.y
end

function Screen:addElement(tblorelem,argstbl,name)
    local tab
    if argstable then
        tab = {tblorelem,argstbl}
        tab.name = name
    else
        tab = tblorelem
        tab.name = tblorelem[3]
    end
    table.insert(self.elements,tab)
end

function Screen:getElementList()
    local v = 0
    for a,b in pairs(self.elements) do
        if b[1] then
            print(a,b.name or "unnamed function","\
",unpack(b[2]))
        else
            print(a,b.name or "(Unnamed class).draw")
        end
    end
end


-- Screens Class

-- Use this function to perform your initial setup
function setup()
    scr = Screen(vec2(20,20))
    table.insert(scr.elements,{background,{0,0,255}})
    table.insert(scr.elements,{ellipse,{WIDTH/2,HEIGHT/2,255}})
    table.insert(scr.elements,Classtest())
    scr.scalefactor = .5
end

-- This function gets called once every frame
function draw()
    scr:draw()
end

function touched(t)
    scr:touched(t)
end

Classtest = class()
function Classtest:init(x)
    self.x = x
end
function Classtest:draw()
    rect(WIDTH/2,HEIGHT/2,1000,1000)
end

@matkatmusic there currently is not, I plan to document it and make an example over the weekend, but currently haven’t the time :slight_smile:

@CayDay47 thank you very much :slight_smile: i plan to keep working on this one to add more features and ease of use. I think it could be a very helpful tool if I make it simple enough to use

Someone should port over the JUCE framework!

There’s a similar idea in one of my projects on CC; it’s in my Library Graphics library in the Layout tab. It integrates with my touch handler to correctly pass touches to all elements inside the block, and also handles rotated screens.

@Monkeyman32123

Here is an example of my PC touch - Please note that the windows are only a minor feature, as I am still working on a way for them to hold minor programs such as text documents and drawings like yours, and to call them up using tables.

https://github.com/CayDay47/Codea_DesktopGUI

The actual main feature at the moment is the implemented game - hope you enjoy.

is there an example of this class in action?

I have realised that there have recently been new interest for a screen/window-based GUI in Codea, as even I started working on one at the start of the year. Great job with this one!

Ah, knew it was something that simple, thank you muchly @LoopSpace :slight_smile:

clips are always with respect to screen coordinates so are unaffected by transformations. Replace that line by:

clip(self.pos.x,self.pos.y, WIDTH*self.scalefactor,HEIGHT*self.scalefactor)

and I think you’ll find it works.