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

Object Oriented Button API v1.1 [Module] [Active]

Started by MatthewC529, 01 August 2014 - 08:56 AM
MatthewC529 #1
Posted 01 August 2014 - 10:56 AM


Object Oriented Buttons v1.1 - Extensible and Flexible - For All People
[indent=1]The Beginning of a Bright Future[/indent]


Being bored and frustrated with current GUI API's I decided to start creating a flexible, object-oriented GUI API (Along with many other utilities) to start mastering Lua while also using my Java experience to benefit myself and others. Those who have programmed in Java will recognize that my GUI API is inspired by the Java Swing Extension in its methodology. Obviously not a port… that would be interesting… just inspired in basic structure and method names.

This API was created to be easy to use for people of all skill levels with the only natural barrier being learning to use the syntactic sugar of object:method() instead of table.method(). This API handles all the dirty work in using the more rudimentary functions of managing Button's, abstracting away all those ugly functions and leaving you with the ability to draw and update buttons with functions as simple as
button.update()
(for simple updates) and
button.update(x, y)
(for touch and click events).

This API was designed to be open to modification and improvement while being a Programmer's dream.

I have several goals when it comes to any API:
  • Simplicity and Intuitive Design
  • Sufficient Extensibility without Degrading User Experience
  • Coherence, Continuity and Completeness
    • Coherent Code with Documentation, Variable Descriptiveness by Scope, and Readable Code
    • Continuity in How Variable's and Function's are named
    • Completeness in the API, Allowing Object's to Be Customizable while also Very Functional
In particular, this API has come out very well following these goals.

As of now this "Module" comes with two main Object's:
  1. Button – Created using button.new(x, y, width, height, [text], [on_color], [off_color].[action])
  2. ButtonGroup – Created using button.newButtonGroup(), Act's in a way similar to Radio Buttons.
* - Square Brackets ("[" and "]") indicate optional parameters, they do not need to be supplied for creation.


Working Example/Notes:
Seeing as this API is Object Oriented there is a slight difference in how objects should be referenced. View below for an example. Since these are Object's they must call any Methods with ":", allowing the table to modify itself. Any non-methods can be referenced normally. Like testButton.width isntead of testButton:getWidth().

A Commented Example:


os.loadAPI("button")

-- Create 4 Buttons, 3 Testing and 1 Exit
local testButton = button.new(2, 2, 20, 2, "Hello World!")
local testButton2 = button.new(2, 6, 20 , 2, "Sup World!")
local testButton3 = button.new(2, 10, 20, 2, "Nice World!")
local exit = button.new(2, 14, 8, 2, "Exit")

--Simple Loop Value
local alive = true

-- Create a Test ButtonGroup
local testGroup = button.newButtonGroup()

-- Simply Applies a different label to a button, adds "!"
function textChange(btn)
  btn:setText(btn:getText().."!")
end

-- Adds 2 Toggleable Buttons to the ButtonGroup,
-- the buttons MUST be toggleable. This acts like
-- radio buttons, only one button in a button group
-- is active at a time.
testGroup:addButtons(testButton2, testButton3)

-- setToFlash make the button non-toggleable. It flashes instead of
-- activating or de-activating and fires it's actions ONCE.
-- Adds TextChange Action to Button, add's a "!" to end of label on click.
testButton:setToFlash()
testButton:addAction(textChange)
exit:setToFlash()
exit:addAction(function() alive = false; end) -- Kill Loop on Click

-- Use button API Methods for utility.
-- Clear Screen and Initial Update to draw buttons
term.clear()
button.update()

while alive do
  event, b, x, y = os.pullEvent("mouse_click")
  button.update(x, y) -- Pass Input X,Y to Update, Any buttons there are activated
  sleep(0.05)
end

term.clear()
term.setCursorPos(1, 1)

All other methods are viewable on github at: https://github.com/M...mputercraft-api


Source Code + Pastebin:

Source Code Can be Viewed At: https://github.com/M...mputercraft-api - (Fixed Syntax Highlighting, all files pushed as .lua from now on)
Pastebin for This Module: http://pastebin.com/049RGK0g – 049RGK0g (Last Updated: 8/2/14 v1.1)

This is likely to be updated commonly, any changes will be noted here and with an updated Pastebin on here and the github page. Most information will be on github since I am working on the Wiki with examples and so on as I plan on extending this into a real GUI framework.

Issues: If you want to, and are able, go ahead and fix them yourself, BUT please either fork the repository, fix it, and submit a Pull Request OR notify me in the GitHub Issues Page or via email (matthewcrocco@gmail.com). PLEASE submit the error, reproducible code and error description or else I will have EXTREME difficulty in fixing issues!

Note: I HIGHLY recommend going to my GitHub for Pastebin Codes! Eventually I will set up MPT and have a PPA set up but for now all pastebin codes WILL be kept up to date, guaranteed, on GitHub. I DO NOT guarantee the pastebin code here will be up to date. It will likely lag behind since it's easier to push to GitHub and update the README as I go. Also you can see all my other neat API's/Modules as they come along! :D/>

Thanks for viewing! Enjoy!

Criticism, comments, recommendations (for this and other projects) appreciated.


Changelog

Spoiler

v1.1


- [Refactor]: Internal Functions of no front-end use encapsulated.
- [Refactor]: Redraw's Added for Visibility changes, destruction, etc.

- [Addition]: Ability to color text
- [Addition]: New button.new() optional parameter (text_color)
[indent=1]- Now is button.new(x, y, width, height, text, on, off, text_color, action)[/indent]
- [Addition]: New Button methods
[indent=1]- Button:setTextColor(color)[/indent]
[indent=1]- Button:getTextColor()[/indent]
[indent=1]- Button:setVisible(boolean)[/indent]
[indent=1]- Button:isVisible()[/indent]
- [Addition]: Ability to destroy Button's and ButtonGroup's properly. (:destroy)
- [Addition]: Visibility Property for Button's (:setVisible(bool), :isVisible())
- [Addition]: ButtonGroup:clear() – Removes all Button's from this Radio Button Group

- [Internal]: Encapsulated forceClear Function, ignores visibility
- [Internal]: Encapsulated redraw Function
- [Internal]: Math Functions (mod, round, etc) encapsulated
- [Internal]: Utility Functions (foreach, foreachi) encapsulated
- [Internal]: local deregister function, user does not need this



Edit: Fixed Syntax Highlighting, Less Sarcastic and Cynical :D/>
Edited on 08 August 2014 - 03:36 PM
Lyqyd #2
Posted 01 August 2014 - 03:29 PM
Moved to APIs and Utilities.
creeperded209 #3
Posted 01 August 2014 - 04:30 PM
@Lyqyd Don't you have to lock this thread??
Engineer #4
Posted 01 August 2014 - 04:35 PM
@Lyqyd Don't you have to lock this thread??
No he doesnt, because actual code is provided in the github link.
MatthewC529 #5
Posted 01 August 2014 - 08:06 PM
Moved to APIs and Utilities.

Apologies, been on this forum for over a year now (just not posting), could have sworn I was in API's and not Operating System's. That's what I get for posting at 5 in the morning…

@Lyqyd Don't you have to lock this thread??
No he doesnt, because actual code is provided in the github link.

Actual code is provided, an example is provided to explain how to use the API in its most fundamental way (Since I currently have no examples on GitHub) and how to use Object's since it is object oriented and most API's I have encountered are Functional only, making me think it would be a good idea to at least explain how to call methods on Objects. It should be handled similar to Vector. This could use a re-design though, again I posted at 5 in the morning so now I will actually make it more clear.

I use the term Object's loosely…