Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal

(Proof of concept) Working/toggleable button

Recommended Posts

Hello everybody! My first posting and first real OC code, so please be gentle ;) .


The reason why I made this is because I got tired of lack of bundled cable support in CC (at the current moment in 1.6.4) and one of the things I greatly enjoyed doing in CC was making button GUI's to control various things for me. This code is highly unoptimized, even as I post this I can see areas that can be greatly optimized, but meh, I'm too lazy atm to do it :D


My one question is how do you change it so you dont have to "sneak-click" the monitor to use the touch feature?


One thing to note of importance. The deliberate delay of "os.sleep(0.1)" between switching the redstone state(s) in the bundled cable IS REQUIRED. Any attempt I made and removing it resulted in the code crashing at random points. I assume its due to trying to change 2 different colored cable states at near the same time (possible bug found?).


Lastly, being I am fairly "noobish" at lua, any 'constructive' tips you can see I should be aware of to help prevent "bad coding habits" I would greatly apperciate it.


Here is a youtube vid of it in action, and the code will follow below. Feel free to use it/edit it/clean it up as you wish!



local component = require("component")
local colors = require("colors")
local sides = require("sides")
local rs = component.redstone
local gpu = component.gpu
local w, h = gpu.getResolution()
local event = require("event")
local Blue = 0x0000AA
local Green = 0x00AA00
local Red = 0xAA0000
local Black = 0x000000
local state = 1

local function cls()
  gpu.fill(1, 1, w, h, " ")

local function buttonState()
  if state == 1 then
    gpu.set(5, 5, "        ")
    gpu.set(5, 6, "  Test  ")
    gpu.set(5, 7, "        ")
    gpu.set(5, 9, "green")
    rs.setBundledOutput(sides.left, colors.red, 0)
    rs.setBundledOutput(sides.left, colors.green, 255)
    state = 2
    gpu.set(5, 5, "        ")
    gpu.set(5, 6, "  Test  ")
    gpu.set(5, 7, "        ")
    gpu.set(5, 9, "red  ")
    rs.setBundledOutput(sides.left, colors.green, 0)
    rs.setBundledOutput(sides.left, colors.red, 255)
    state = 1
local function default()
  gpu.set(5, 5, "        ")
  gpu.set(5, 6, "  Test  ")
  gpu.set(5, 7, "        ")
  gpu.set(5, 9, "blue ")
  rs.setBundledOutput(sides.left, colors.red, 0)
  rs.setBundledOutput(sides.left, colors.green, 0)

gpu.setResolution(83, 30)
gpu.fill(1, 1, w, h, " ")

while true do
  local _, _, x, y = event.pull(touch)
    if x >= 5 and x <= 12 then
      if y >= 5 and y <= 7 then
Link to post
Share on other sites

Aha. I see you're hard at work on your very own solution! Allow me to give a tip or 5 :)


Today we'll talk a little about OOP or Object Oriented Programming. Now, in lua, OOP is a little different than in other more popular OOP languages such as JAVA.

So for you guys out there who would say lua doesnt have oop... You probably know better than me. With that said lets learn some stuff about simulating OOP in lua.


First off there are tables. myTable = {}. In lua tables are used as objects because every table created is unique. Not table references though. i.e. myTableA = myTable, this is referencing myTable.


With this in mind we can create objects with behavior relevant to that object. Still following? Example:

local Bob = {}
  Bob.name = "Bob"
  Bob.age = "32"
-- ## Bob works 40/60 hrs per week so he cant play enough MC with OC  . Must support them lousy kids. >
  Bob.familyMan = true

function Bob.introduce()
  return "Hi, my name is " .. Bob.name .. ". I'm " .. Bob.age .. " years old."

print(Bob.introduce()) --> output: "Hi, my name is Bob. I'm 32 years old."


If you notice the Bob object has specific fields, name and age, that identify him. The fields arent so unique but the Bob object is.

Bob isnt very flexible as an object though. This brings me to Classes. Classes are Objects. But, they are not the same as lets say Bob.

Bob is an instance of a Class. We usually wont interact with a class like we would an instance of a class. For example:

-- ## This is a class
local Person = {}

function Person.create( name, age )
  -- ## This is our instance of this class
  -- ## It will be unique and relevant to the 'Person' class and act like a 'Person'
  local newPerson = {}
    newPerson.name = name
    newPerson.age = age
   -- ## notice newPerson.introduce is actually the same function value as Person.introduce
   -- ## its main argument is the table or 'instance' of a person
    newPerson.introduce = Person.introduce
  return newPerson

function Person.introduce( person ) -- ## notice the argument isn't 'Person' but a 'person' instance
  return "Hi, my name is " .. person.name ..". I'm " .. person.age .. " years old."

-- ## Here we create a new instance of the 'Person' class named "Al" and stored in the variable 'Al'
local Al = Person.create( "Al", 28 )
-- ## Here we use a Class method(function) that operates on our Class instances.
-- ## It can do this because the class knows how to treat an instance of its class.
print( Person.introduce( Al ) ) -- > output like before but with "Al" age "28"
-- ## Or we can call it like so from the instance:
print( Al:introduce() ) --> notice the colon ':' syntax instead of a dot '.'
-- ## A colon between a table and a method(function) in that table will pass the table to the function as the first argument
-- ## Its is exactly the same as:
print( Al.introduce( Al ) )


Now for my main point.. Buttons. Buttons are a class. We want uniqueness and specified behavior.

local Button = {} -- ## This is our class declaration not our instance of a button we'd use

-- ## This is an 'instance constructor'. It makes making new button objects easy
function Button.create( text, x, y, width, height, color )
  local newButton = {
     text = text, -- ## newButton.text = text(argument)
     x = x,
     y = y,
     width = width,
     height = height,
     color = color,
     draw = Button.draw

function Button.draw( self )
  -- ## 'self' here is the reference to the button instance itself not the 'Button' class
  local oldColor = gpu.setBackground( color )
  gpu.fill( self.x, self.y, self.width, self.height, " " )
  -- ## im not centering the text here.. just an example..
  gpu.set( self.x, self.y, self.text )
  gpu.setBackground( oldColor )
  return true -- not really necessary just good to have returned something..

-- ## instances that we would use.
local button1 = Button.create( 'test1', 4, 4, 10, 3, 0x00FF00 )
local button2 = Button.create( 'test2', 4, 8, 12, 5, 0x0000FF ) -- ps i dont know wtf these colors are...

button1:draw() -- ## draw button 1.


I hope this will help you understand the power of OOP like design and some of the more basic ways to use it :)

As usual any questions or elaborations by others are welcome. If someone else can explain better please do! lua is my first language!

Link to post
Share on other sites
On 9/6/2014 at 3:40 PM, Molinko said:


Color codes aren't terribly difficult: it's broken down into 3 section, red green and blue. Each section gets two characters, and those characters are hexadecimal - FF is hexadecimal for 255. So FF0000 would be entirely red, 00FF00 would be entirely green, and 0000FF would be entirely blue.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.