Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Buttons

edited August 2012 in Examples Posts: 5

Hello, I want to make an app with a button. Mine idea was that if you touch the button, you will see something like a dark background ir something in that way. Can you help me guys?

Tagged:

Comments

  • Posts: 371

    Hey @pepijnpp. Here is @Vegas button class, feel free to use it.

    --Much faster version of button class by Vega
    button = class()
    function button:init(text,location,width,height)
        self.state = "normal"
        self.text = text
        self.textColor = color(255,255,255,192)
        self.location = location
        self.width = width
        self.height = height
        self.visible = true
        self.fontSize = 28
        self.font = "ArialRoundedMTBold"
        self.color1 = color(255, 255, 255, 96)
        self.color2 = color(128,128,128,32)
        self.presscolor1 = color(192, 224, 224, 128)
        self.presscolor2 = color(96, 192, 224, 128)
        self.verts = self:createVerts(self.width, self.height)
        self.myMesh = mesh()
        self.myMesh.vertices = triangulate(self.verts)
        self.vertColor = {}
        self:recolor()
    end
    function button:setColors(c1,c2,p1,p2)
        self.color1 = c1
        self.color2 = c2
        self.presscolor1 = p1
        self.presscolor2 = p2
        self:recolor()
    end
    function button:textOptions(fn, sz, col)
        self.font = fn
        self.fontSize = sz
        self.textColor = col
    end
    function button:draw()
        if self.visible == true then
            pushMatrix()
            translate(self.location.x,self.location.y)
            self.myMesh:draw()
            fill(self.textColor)
            fontSize(self.fontSize)
            font(self.font)
            text(self.text, self.width/2,self.height/2)
            self:drawLines(self.verts)
            popMatrix()
        end
    end
    function button:touched(touch)
        if self.visible then
            if touch.x >= self.location.x and touch.x <= self.location.x + self.width and touch.y >= self.location.y and touch.y <= self.location.y + self.height then
                if touch.state == BEGAN then
                    self.state = "pressing"
                    self:recolor()
                elseif touch.state == ENDED then
                    if self.state == "pressing" then
                        self.state = "normal"
                        self:recolor()
                        print "pressed."
                    end
                end
            else
                self.state = "normal"
                self:recolor()
            end
        end
    end
    function button:createVerts(w,h)
        local r
        local v = {}
        if w > 100 or h > 100 then
            if w>=h then r = round(h/100) else r = round(w/100) end
        else
            r = 1
        end
        v[1] = vec2(w,6*r)
        v[2] = vec2(w-r,4*r)
        v[3] = vec2(w-2*r,2*r)
        v[4] = vec2(w-4*r,r)
        v[5] = vec2(w-6*r,0)
        v[6] = vec2(6*r,0)
        v[7] = vec2(4*r,r)
        v[8] = vec2(2*r,2*r)
        v[9] = vec2(r,4*r)
        v[10] = vec2(0,6*r)
        v[11] = vec2(0,h-6*r)
        v[12] = vec2(r,h-4*r)
        v[13] = vec2(2*r,h-2*r)
        v[14] = vec2(4*r,h-r)
        v[15] = vec2(6*r,h)
        v[16] = vec2(w-6*r,h)
        v[17] = vec2(w-4*r,h-r)
        v[18] = vec2(w-2*r,h-2*r)
        v[19] = vec2(w-r,h-4*r)
        v[20] = vec2(w,h-6*r)
        return v
    end
    function button:drawLines(v)
        pushStyle()
        noSmooth()
        strokeWidth(1)
        stroke(0, 0, 0, 192)
        for i=1, #v-1 do
            line(v[i].x,v[i].y,v[i+1].x,v[i+1].y)
        end
        line(v[#v].x,v[#v].y,v[1].x,v[1].y)   
        popStyle()
    end
    function button:recolor()
        local lt, dk
        if self.state == "normal" then 
            lt = self.color1
            dk = self.color2
        else
            lt = self.presscolor1
            dk = self.presscolor2
        end
        for i=1,3 * #self.verts - 6 do
            if self.myMesh.vertices[i].y > self.height/2 then
                self.vertColor[i] = lt
            else
                self.vertColor[i] = dk
            end
        end
        self.myMesh.colors = self.vertColor
    end
    function round(v)
        return math.floor(v + 0.5)
    end
    
    

    Enjoy!
    P.S. I am working on a button class of my own... ;) Be excited...

  • Posts: 563

    .@pepijnpp - I use the @Vega button class as well, with some minor mods to add a call back function (so you can do something when the button is tapped), you can get a copy here: https://www.dropbox.com/s/crrhfz8kdde4z6v/Button.lua

    Or if you want a simpler solution then look at: http://codeatuts.blogspot.com.au/2012/06/tutorial-3-simple-button-class.html

  • Jmv38Jmv38 Mod
    edited September 2012 Posts: 3,295

    Thank you @Reefwing just grabbed your class cause i needed a callback too: your buttons are beautiful and work fine. I am always amazed how natural and smooth it is to program in lua: i just copied you code, typed a few lines and it works directly as expected, no bug! I've done quite some programming in Javascript, that's a different story: i almost get one error for each line of code and it takes the hell of a time to have something that finally works. I worship LUA!

  • Posts: 563

    Hi @Jmv38 - I wish I could take the credit! However the look and feel of the button is courtesy of @Vega and the call back functionality is courtesy of the example code in the Sounds Plus App which comes with Codea. I just stuck them together.

    I agree about Lua though, I'm working with Objective C as well and there is a huge difference in complexity and transparency. Even doing something simple in Objective C isn't simple.

  • Am new here so maybe this has been answered elsewhere.

    Since Codea can use sprites, of what use is it to have all that code just to draw a single button? Wouldn't it be simpler to use a button image (sprite) and add the code to harness the touched events?

  • Posts: 563

    .@bernbout - using sprites is a perfectly valid approach as well. In fact my next tutorial (probably out today) will use that method. It is best suited if you want something that looks a bit fancy. The advantage of the mesh approach is that the class is standalone (you dont need to include the sprite assets) and it takes less memory.

  • @Reefwing Thanks for clearing that up. I take a more visual approach to programming and prefer to see rather than pure code. I appreciate the usage of the code class where the colours can easily be changed with one line rather than uploading a new sprite.

    I know most of Codea is focused on games but there are also Applications and I was wondering how difficult it would be to tap into the IOS native controls and use them instead of programming them completely in Lua. Maybe a bridge-like class that "Implements" native controls? Is that at all feasible?

    Why I ask is that I also use Stencyl (stencyl.com) and the guys there have implemented a native text label control for IOS because the other way was eating up GPU cycles and fps. It just is a code block that taps into the native IOS label control.

    Your tutorials are excellent though assume prior knowledge in some cases. I am going thru them one by one. I await your latest tutorial. Thanks for your reply.

  • Posts: 116

    I bet we can turn that button into a text box with ease....
    Have the touch show the keyboard, update the button text.
    I'll play with it.

  • Hi .@bernbout - My understanding is that most of the rendering for Codea is done using OpenGL. The iOS controls you are speaking off are part of UIKit which isn't exposed in Codea (AFAIK). I don't know how hard it would be to implement this but I suspect it is non-trivial or it would have been done already. The quest for the perfect button is ongoing as you will see from the frequency of this topic. @Andrew_Stacey has produced a library which you might want to have a look at.

    Glad you are enjoying the tutes and thanks for the feedback - I'm working on the next one at the moment.

  • Button to TextBox.
    Could use some enhancements, like auto size


    Textbox = class() -- Fast Mesh Button Class courtesy of @Vega -- 3 Aug 2012 -- -- Modified: - Call Back Functionality added --           - pushStyle() & popStyle() added to draw() --           - tapped status added --           - pointInRect() function added --           - changed vec2 location to x and y (to reduce typing!) -- -- Version 1.3 (4 Aug 2012) function Textbox:init(text,x,y,width,height)     self.state = "normal"     self.text = text     self.textColor = color(255,255,255,192)     self.x = x     self.y = y     self.width = width     self.height = height     self.visible = true     self.fontSize = 28     self.font = "ArialRoundedMTBold"     self.color1 = color(255, 255, 255, 96)     self.color2 = color(128,128,128,32)     self.presscolor1 = color(192, 224, 224, 128)     self.presscolor2 = color(96, 192, 224, 128)     self.verts = self:createVerts(self.width, self.height)     self.myMesh = mesh()     self.myMesh.vertices = triangulate(self.verts)     self.vertColor = {}     self:recolor()     self.action = nil     self.tapped = false end function Textbox:setColors(c1,c2,p1,p2)     self.color1 = c1     self.color2 = c2     self.presscolor1 = p1     self.presscolor2 = p2     self:recolor() end function Textbox:textOptions(fn, sz, col)     self.font = fn     self.fontSize = sz     self.textColor = col end function Textbox:draw()     if self.visible == true then         pushStyle()         pushMatrix()         translate(self.x,self.y)         self.myMesh:draw()         fill(self.textColor)         fontSize(self.fontSize)         font(self.font)         text(self.text, self.width/2,self.height/2)         self:drawLines(self.verts)         popMatrix()         popStyle()     end end function Textbox:touched(touch)     self.tapped = false     if self.visible then           if pointInRect(touch.x, touch.y, self.x, self.y, self.width, self.height) then             if touch.state == BEGAN then                 self.tapped = true                 self.state = "pressing"                 self:recolor()                 self.text =""                 showKeyboard()             elseif touch.state == ENDED then                 if self.state == "pressing" then                     self.state = "normal"                     self.tapped = true                     self:recolor()                 end                 if self.action then                     self.action()                 end             end         else             self.state = "normal"             self:recolor()         end     end end function Textbox:createVerts(w,h)     local r     local v = {}     if w > 100 or h > 100 then         if w>=h then r = math.round(h/100) else r = math.round(w/100) end     else         r = 1     end     v[1] = vec2(w,6*r)     v[2] = vec2(w-r,4*r)     v[3] = vec2(w-2*r,2*r)     v[4] = vec2(w-4*r,r)     v[5] = vec2(w-6*r,0)     v[6] = vec2(6*r,0)     v[7] = vec2(4*r,r)     v[8] = vec2(2*r,2*r)     v[9] = vec2(r,4*r)     v[10] = vec2(0,6*r)     v[11] = vec2(0,h-6*r)     v[12] = vec2(r,h-4*r)     v[13] = vec2(2*r,h-2*r)     v[14] = vec2(4*r,h-r)     v[15] = vec2(6*r,h)     v[16] = vec2(w-6*r,h)     v[17] = vec2(w-4*r,h-r)     v[18] = vec2(w-2*r,h-2*r)     v[19] = vec2(w-r,h-4*r)     v[20] = vec2(w,h-6*r)     return v end function Textbox:drawLines(v)     noSmooth()     strokeWidth(1)     stroke(0, 0, 0, 192)     for i=1, #v-1 do         line(v[i].x,v[i].y,v[i+1].x,v[i+1].y)     end     line(v[#v].x,v[#v].y,v[1].x,v[1].y)    end function Textbox:recolor()     local lt, dk     if self.state == "normal" then          lt = self.color1         dk = self.color2     else         lt = self.presscolor1         dk = self.presscolor2     end     for i=1,3 * #self.verts - 6 do         if self.myMesh.vertices[i].y > self.height/2 then             self.vertColor[i] = lt         else             self.vertColor[i] = dk         end     end     self.myMesh.colors = self.vertColor end -- Math Utilities function math.round(value)          -- math.round function courtesy of Vega.          return math.floor(value + 0.5)      end function Textbox:keyboard(key) self.text = self.text..key end      function pointInRect(pointX, pointY, x, y, w, h)          -- Returns true if point (pointX, pointY) is within the rectangle     -- with lower left corner at (x, y) with a width of w and a     -- height of h.     --     -- Reefwing Software (www.reefwing.com.au)     -- Version 1.0          if pointX >= x and pointX <= x + w and pointY >= y and pointY <= y + h then         return true     else         return false     end      end
Sign In or Register to comment.