This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
BlankWolf's profile picture

[CC 1.5] ButtonAPI

Started by BlankWolf, 01 July 2013 - 09:37 AM
BlankWolf #1
Posted 01 July 2013 - 11:37 AM
Hello everyone,

I made an API for creating some buttons on a computer or monitor.
I know there are already button apis posted, but I wanted to show you own.

Download:
http://pastebin.com/6A8JuwqB

API-code:
Spoiler

local objects = {}

function newButton(array)
        if(not term.isColor()) then error('you have to use an advanced computer/monitor',2) end
        if(type(array) ~= 'table' and type(array) ~= 'nil') then error('Expectet \'table\' got \''..type(array)..'\'',2) end
        local self = {}

        if(type(array) == 'nil') then array = {} end

        local title = array.title or ''
        local posX = array.posX or 0
        local posY = array.posY or 0
        local width = array.width or 0
        local height = array.height or 0
        local tcolor = array.textcolor or colors.black
        local bcolor = array.backgroundcolor or colors.red
        local active = array.active or false
        local funct = array.funct or function() return false end
        local termX, termY = term.getSize()

        if(width <= 0 or height <= 0 or posX+width > termX or posY+height > termY) then
                active = false
        end

        table.insert(objects, self)

        function self.getTitle()
                return title
        end
        function self.getPosX()
                return posX
        end
        function self.getPosY()
                return posY
        end
        function self.getWidth()
                return width
        end
        function self.getHeight()
                return height
        end
        function self.getTextColor()
                return tcolor
        end
        function self.getBackgroundColor()
                return bcolor
        end
        function self.getActive()
                return active
        end
        function self.getDraw()
                return draw
        end

        function self.setTitle(str)
                if(type(str) ~= 'string' and type(str) ~= 'number') then error('Expectet \'string\' or \'number\' got \''..type(str)..'\'',2) end
                title = ''..str
                return true
        end
        function self.setPosX(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                termX, termY = term.getSize()
                if(width <= 0 or height <= 0 or posX+width > termX or posY+height > termY) then
                        active = false
                end
                posX = int
                return true
        end
        function self.setPosY(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                termX, termY = term.getSize()
                if(width <= 0 or height <= 0 or posX+width > termX or posY+height > termY) then
                        active = false
                end
                posY = int
                return true
        end
        function self.setWidth(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                termX, termY = term.getSize()
                if(width <= 0 or height <= 0 or posX+width > termX or posY+height > termY) then
                        active = false
                end
                width = int
                return true
        end
        function self.setHeight(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                termX, termY = term.getSize()
                if(width <= 0 or height <= 0 or posX+width > termX or posY+height > termY) then
                        active = false
                end
                height = int
                return true
        end
        function self.setTextColor(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                tcolor = int
                return true
        end
        function self.setBackgroundColor(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                bcolor = int
                return true
        end
        function self.setActive(bool)
                if(type(bool) ~= 'boolean') then error('Expectet \'boolean\' got \''..type(bool)..'\'',2) end
                termX, termY = term.getSize()
                if(width <= 0 or height <= 0 or posX+width > termX or posY+height > termY) then
                        active = false
                        return false
                end
                active = bool
                return true
        end
        function self.setFunction(funct)
                if(type(funct) ~= 'function') then error('Expectet \'function\' got \''..type(funct)..'\'',2) end
        end

        function self.changeTitle(str)
                if(type(str) ~= 'string' and type(str) ~= 'number') then error('Expectet \'string\' or \'number\' got \''..type(str)..'\'',2) end
                if(self.setTitle(str)) then
                        self.draw()
                        return true
                end
                return false
        end
        function self.changePosX(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                if(self.setPosX(int)) then
                        self.draw()
                        return true
                end
                return false
        end
        function self.changePosY(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                if(self.setPosY(int)) then
                        self.draw()
                        return true
                end
                return false
        end
        function self.changeWidth(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                if(self.setWidth(int)) then
                        self.draw()
                        return true
                end
                return false
        end
        function self.changeHeight(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                if(self.setHeight(int)) then
                        self.draw()
                        return true
                end
                return false
        end
        function self.changeTextColor(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                if(self.setTextColor(int)) then
                        self.draw()
                        return true
                end
                return false
        end
        function self.changeBackgroundColor(int)
                if(type(int) ~= 'number') then error('Expectet \'number\' got \''..type(int)..'\'',2) end
                if(self.setBackgroundColor(int)) then
                        self.draw()
                        return true
                end
                return false
        end

        function self.draw()
                if(not active) then return false end
                oldX, oldY = term.getCursorPos()
                term.setBackgroundColor(bcolor)
                term.setTextColor(tcolor)
                for y=0, height-1 do
                        term.setCursorPos(posX, posY+y)
                        for x=1, width do
                                write(' ')
                        end
                end
                term.setCursorPos(math.floor((width - #string.sub(title,1,width)) / 2) + posX, math.floor(height / 2) + posY)
                write(string.sub(title,1,width))

                term.setCursorPos(oldX, oldY)
                term.setBackgroundColor(colors.black)
                term.setTextColor(colors.white)
                draw = true
                return true
        end
        function self.runFunction(...)
                funct(...)
        end

        return self
end

function getButton(posX, posY)
        if(type(posX) ~= 'number') then error('posX: expectet \'number\' got \''..type(posX)..'\'',2) end
        if(type(posY) ~= 'number') then error('posY: expectet \'number\' got \''..type(posY)..'\'',2) end
        for number, obj in pairs(objects) do
                if(obj.getActive() and obj.getDraw()) then
                        if(posX >= obj.getPosX() and posX < obj.getPosX() + obj.getWidth() and posY >= obj.getPosY() and posY < obj.getPosY() + obj.getHeight()) then
                                return obj
                        end
                end
        end
        return dummy
end

available functions:
Spoiler

get/set/changeTitle()  -- set and change needs a string
get/set/changeWidth()  -- set and change needs a number
get/set/changeHeight()  -- set and change needs a number
get/set/changePosX()  -- set and change needs a number
get/set/changePosY()  -- set and change needs a number
get/set/changeTextColor()  -- set and change needs a number
get/set/changeBackgroundColor()  -- set and change needs a number
get/setActive()  -- set needs a boolean
getDraw()
draw()
runFunction()  -- you can use arguments
getButton()

usage:
SpoilerFirst load the API.
os.loadAPI("button")

Than you can create a new button like so,
b1 = button.newButton()
-- notice: you can't draw this button

or you give the button some arguments (you don't have to use all).
b2 = button.newButton({title='test'; width=11; height=3; posX=5; posY=5; backgroundcolor=colors.red; textcolor=colors.black; active=true; func=function(int) print(int+1) end})
-- notice: when the width/height == 0 or width+posX/height+posY > then the screen or active == false you can't draw the button either!
-- notice: when the title is lager then the button, the title will be cutoff
-- notice: the arguments need to be in a table or you get an error

If the button is created you can get or set the arguments. For example:
b2.getWidth()	-- this will return 11
b2.setWidth(9)   -- set the width off b2 to 9 and return true by success
b2.getWidth()	-- this time it returns 9

When you'r happy with your arguments you can draw the button to the screen.
b2.draw()

You also can run a function wich is bound to a button
b2.runFunction(5)  -- in this example it prints 6 to the screen

Finally you can get a button by his position and change the arguments.
event, button, x, y = os.pullEvent('mouse_click')
button.getButton(x,y).changeTitle('newTitle')
-- notice: you can only use change, when the button is allready drawed to the screen, otherwise it will return false

For an ingame help start my api like a normal program with "help" has an argument.
button  help

example program:
Spoiler



-- load the api
os.unloadAPI("button")
os.loadAPI("button")

termX,termY = term.getSize()
shell.run("clear")
term.setCursorPos(1,termY)

funct = function()
end

-- create some buttons
b1 = button.newButton({title='b1';posX=5;posY=2;width=9;height=3;active=true;funct=function(x,y) term.clearLine() term.setCursorPos(x,y) end})
b2 = button.newButton({title='b2';posX=5;posY=6;width=9;height=3})
b3 = button.newButton({title='b3';posX=5;posY=10;width=9;height=3;active=true;funct=function() write(5) end})

-- draw the buttons
b1.draw()
b2.draw()
b3.draw()


while true do
        e = {os.pullEvent('mouse_click')}
        obj = button.getButton(e[3],e[4])
        if(obj.getBackgroundColor() == colors.red) then
                obj.changeBackgroundColor(colors.lime)
        else
                obj.changeBackgroundColor(colors.red)
        end
        obj.runFunction(1,termY)
end

http://pastebin.com/up7K08ZQ

changelog:
Spoilerv1.1 - add a new function (runFunction) and a button argument (func)

please report any bugs or ideas what I can add or change

thanks
BlankWolf
svdragster #2
Posted 02 July 2013 - 01:19 PM
Nice job! But you should definetly include an explanation here instead only in the program!
BlankWolf #3
Posted 03 July 2013 - 02:14 AM
Nice job! But you should definetly include an explanation here instead only in the program!

Thanks. Your right I have add an explanation under usage.
Do you have an idea what feature can be added?
svdragster #4
Posted 03 July 2013 - 01:01 PM
I can't think of more features… not yet :P/>
BlankWolf #5
Posted 03 July 2013 - 01:17 PM
Update the API to v1.1
Have a look to the changelogs.
UMayBleed #6
Posted 04 July 2013 - 03:56 PM
Well I made a GUI api (Not public yet) that does the same thing pretty much, it checks each button if its in the area of the click. Though this is nice!
BlankWolf #7
Posted 05 July 2013 - 01:47 AM
Well I made a GUI api (Not public yet) that does the same thing pretty much, it checks each button if its in the area of the click. Though this is nice!

Thanks.
I will make a GUI api too. (someday)
wolfhowl42 #8
Posted 07 July 2013 - 11:40 PM
kinda confusing
BlankWolf #9
Posted 08 July 2013 - 01:53 AM
kinda confusing

What exactly are you confused about?
Cutecurtain #10
Posted 10 July 2013 - 04:56 AM
Very useful. Easy to read through the code as well :)/> Nice job
BlankWolf #11
Posted 10 July 2013 - 05:24 AM
Very useful. Easy to read through the code as well :)/> Nice job
Thanks.
If you have any suggestion what can be added or change feel free to post it ;)/>
oedze #12
Posted 22 July 2013 - 01:10 PM
looks nice, but i dont need it right now. i will follow your topic incase i need one ;)/>
BlankWolf #13
Posted 24 July 2013 - 02:04 AM
looks nice, but i dont need it right now. i will follow your topic incase i need one ;)/>

Thanks.
Go ahead. Use my API when ever you want.
But I'am still rewriting the code… Well I will rewrite it, when I have time for it ;)/>
jesusthekiller #14
Posted 24 July 2013 - 05:55 AM
Thanks.
Go ahead. Use my API when ever you want.
But I'am still rewriting the code… Well I will rewrite it, when I have time for it ;)/>

Maintaining part sucks :P/>
BlankWolf #15
Posted 24 July 2013 - 06:54 AM
Maintaining part sucks :P/>

Well… I don't think so.
I like it when I can make my program better than before ;)/>
jesusthekiller #16
Posted 24 July 2013 - 12:36 PM
I hate it tho :P/>
figgycity50 #17
Posted 29 July 2013 - 11:41 AM
am i doing something wrong or is this broken? my error:
BlankWolf #18
Posted 30 July 2013 - 01:57 AM
am i doing something wrong or is this broken? my error:

Well no. It's my fault.
I think I fixed it, but I can't test it atm.
LeB0ucEtMistere #19
Posted 16 August 2013 - 04:22 PM
nice work :)/> pretty useful, i will get some inspiration of your design to code my own API i tough ^^' indeed, that's a nice job ! keep it up :)/>
BlankWolf #20
Posted 19 August 2013 - 02:06 AM
nice work :)/> pretty useful, i will get some inspiration of your design to code my own API i tough ^^' indeed, that's a nice job ! keep it up :)/>

Thanks, I'm glad that my code is useful for you. And don't worry. I will keep it up. I just haven't enough time. D=
RepeaterCreeper #21
Posted 19 August 2013 - 09:34 AM
Nice API! Will definitely help with my Redstone stuff. :D/>
eningly #22
Posted 27 August 2013 - 04:08 PM
hello i love your api but i have a little problem maybe you can help i am linking whit the draw butten and fuction funcion of the buttons to a other function whit a button from this api in it but that button wont work i will post a pastebin link in a edit as you dont understand
BlankWolf #23
Posted 28 August 2013 - 01:53 AM
hello i love your api but i have a little problem maybe you can help i am linking whit the draw butten and fuction funcion of the buttons to a other function whit a button from this api in it but that button wont work i will post a pastebin link in a edit as you dont understand
Yes please poste your code. Thats easier to understand and so I can "maybe" see where the problem is.
eningly #24
Posted 28 August 2013 - 03:57 AM
http://pastebin.com/JRUD9fFh

this is te link but it is a little bit of your script whit some more code
BlankWolf #25
Posted 28 August 2013 - 07:53 AM
Why is ther so often:

funct=function()
end
I can't see what this is good for.



55. obj.runFunction(1,termY)
you wanna run a function whit parameter. Thats fine and will work. BUT you have du implement your functions so, they can handle these parameter.

39. b3 = button.newButton({title='b3';posX=5;posY=10;width=9;height=3;active=true;funct=function(x,y) term.setCursorPos(x, y)write(5) end})

And now to your problem:
you create a new button (line 23) an the same coordinates b1 (line 37) is bevor. But the getButton function will find the first createt button (in that case b1 from line 37) first and return it. So the other b1 (line 23) will never get found.

23. b1 = button.newButton({title='back';posX=5;posY=2;width=9;height=3;active=true;funct=function() print("hello worlfd") end;})

-- snipe --

37. b1 = button.newButton({title='pass';posX=5;posY=2;width=9;height=3;active=true;funct=function()  pass()  end})

if you wanna do this, you have do deactivate your buttons and than make a new on the same coordinates:
b1.setActive(false)

or

just override the function of b1 so you don't have to create it again ;)/>
b1.setFunction(function() print("hello worlfd"))

——————–
but thanks.
you gave me some ideas to improve the api to handle this problem :D/>
eningly #26
Posted 28 August 2013 - 08:53 AM
oke thanks man jhe the trash code whas for figgering it out myself oke now i understand thanks