[ComputerCraft] Touchscreen Button Solutions!

  • Please make sure you are posting in the correct place. Server ads go here and modpack bugs go here
  • The FTB Forum is now read-only, and is here as an archive. To participate in our community discussions, please join our Discord! https://ftb.team/discord

RavynousHunter

New Member
Jul 29, 2019
2,784
-3
1
I've been hacking away for the past 2-3 hours on a flexible, object-oriented way to implement touchscreen buttons for ComputerCraft. I think I've gotten the main meat of the code down, two classes (Point and Button), implementation, searching and finding functions, button lookup table which can be altered with two simple functions, AddButton() and RemoveButton().

For those who are interested, check the spoiler below...
Code:
-- BEGIN Point class
 
Point = { }
Point.__index = Point
 
function Point.create( x, y )
  assert( type( x ) == "number", "Point.create() expects argument 'x' to be number or nil." )
  assert( type( y ) == "number", "Point.create() expects argument 'y' to be number or nil." )
 
  local pt = { }
  setmetatable( pt, Point )
 
  pt.x = x
  pt.y = y
 
  return pt
end
 
function Point:setX( x )
  assert( type( x ) == "number", "Point.setX() expects a number or nil." )
  self.x = x
end
 
function Point:setY( y )
  assert( type( y ) == "number", "Point.setY() expects a number or nil." )
  self.y = y
end
 
function Point:getX()
  return self.x
end
 
function Point:getY()
  return self.y
end
 
-- END Point class
 
-- BEGIN Button class
 
Button = { }
Button.__index = Button
 
function Button.create( location, text, event_msg, text_color, back_color )
  assert( type( location  ) == "Point",  "Button constructor expects a Point as first argument."      )
  assert( type( text      ) == "string", "Button constructor expects a string as second argument."    )
  assert( type( event_msg  ) == "string", "Button constructor expects a string as third argument."      )
  assert( type( text_color ) == "string", "Button constructor expects a string as the fourth argument." )
  assert( type( back_color ) == "string", "Button constructor expects a string as the fifth argument."  )
 
  local btn = { }
  setmetatable( btn, Button )
 
  btn.loc:setX( location:getX() )
  brn.loc:setY( location:getY() )
 
  btn.text      = text
  btn.evt_msg    = event_msg -- Message to be passed along whenever Button is clicked
  btn.text_color = text_color
  btn.back_color = back_color
 
  return btn
end
 
function Button:setLoc( location )
  assert( type( location ) == "Point", "Button:setLoc() expects a Point." )
 
  self.loc:setX( location:getX() )
  self.loc:setY( location:getY() )
end
 
function Button:getLoc()
  return self.loc
end
 
function Button:setText( txt )
  assert( type( txt ) == "string", "Button:setText() expects a string." )
  self.text = txt
end
 
function Button:getText()
  return self.text
end
 
function Button:setEventMessage( msg )
  assert( type( msg ) == "string", "Button:setEventMessage() expects a string." )
  self.evt_msg = msg
end
 
function Button:getEventMessage()
  return self.evt_msg
end
 
button_table = { }
table_size  = 0
 
function SearchButtonTableByText( text )
  assert( type( text ) == "string", "SearchButtonTableByText() expects a string."  )
 
  if ( table_size < 1 ) then
    return false
  else if ( table_size == 1 ) then
    if ( button_table[1]:getText() == text ) then
      return true
    else
      return false
    end
  else
    for i = 1, table_size do
      if ( button_table[i]:getText() == text ) then
        return true
      end
    end
    return false
  end
end
 
function SearchButtonTableByLoc( location )
  assert( type( location ) == "Point", "SearchButtonTableByLoc() expects a Point." )
 
  if ( table_size < 1 ) then
    return false
  else if ( table_size == 1 ) then
    if ( button_table[1]:getLoc() == location ) then
      return true
    else
      return false
    end
  else
    for i = 1, table_size do
      if ( button_table[i]:getLoc() == location ) then
        return true
      end
    end
    return false
  end
end
 
function FindButtonByText( text )
  assert( type( text ) == "string", "FindButtonByText() expects a string." )
 
  if ( table_size < 1 ) then
    return nil
  else if ( table_size == 1 ) then
    if ( button_table[1]:getText() == text ) then
      return 1
    else
      return nil
    end
  else
    for i = 1, table_size do
      if ( button_table[i]:getText() == text ) then
        return i
      end
    end
    return nil
  end
end
 
function FindButtonByLoc( location )
  assert( type( location ) == "Point", "FindButtonByLoc() expects a Point." )
 
  if ( table_size < 1 ) then
    return nil
  else if ( table_size == 1 ) then
    if ( button_table[1]:getLoc() == location ) then
      return 1
    else
      return nil
    end
  else
    for i = 1, table_size do
      if ( button_table[i]:getLoc() == location ) then
        return i
      end
    end
    return nil
  end
end
 
-- AddButton( Button button )
-- Adds a button to the button list, if the text of
-- the passed button doesn't match any other, and if
-- it does not have the same location.
function AddButton( button )
  assert( type( button ) == "Button", "AddButton() expects a Button." )
 
  if ( SearchButtonTableByText( button:getText() ) == false ) then
    if ( SearchButtonTableByLoc( button:getLoc() ) == false ) then
      table.insert( button_list, button )
      table_size = table_size + 1
 
      return true
    else
      return false
    end
  else
    return false
  end
end
 
function RemoveButton( button )
  assert( type( button ) == "Button", "RemoveButton() expects a Button." )
 
  if ( FindByText( button:getText() ) != nil ) then
    if ( FindByLoc( button:getLoc() ) != nil ) then
      table.remove( button_list, FindByText( button:getText() ) )
      table_size = table_size - 1
 
      return true
    else
      return false
    end
  else
    return false
  end
end

Just as a note, this code is currently untested, so I'm not sure if it works yet, but I tried to follow the Lua docs and various bits I researched as best as I could. I wanted to go with an object-oriented approach because, as a C# programmer, its the paradigm I'm most used to and the one with which I'm most familiar. I also tried to implement as much run-time type checking as I could, so I could prevent those sneaky little type-related bugs I know can come up if you're not careful, especially with a language that's got more flexible types like Lua.

Anyone spot any problems? Suggestions? Comments? Criticisms? Anyone else come up with a way to make touchscreen monitor buttons for ComputerCraft easier to deal with?

[ETA]
I probably should've commented that code better...alas, spending most of my time working on a programming team consisting of exactly one person (myself), tis not something I'm wholly used to. I will once I've gotten things working and tested, at least.

The whole reason I'm doing this, myself, is to make a monster farming room setup as thus:

Computer 0: The main input computer, hooked up to the touch screen monitor. Whenever a button is clicked, it sends a given message (the evt_msg of the Button class) to the spawn control computer.

Spawn Control Computer: Upon receiving a message, it will have a pre-loaded list associating the messages with colors of RedPower insulated wiring, each one connected to its own, unique creature spawner thru bundled cabling.

Though, this system DOES have one limitation: I'd only be able to have up to 16 spawners connected to the Spawn Control Computer. However, I -could- redirect the rednet messages that Computer 0 normally sends to the SCC to a message interpreting/routing computer, which will associate the received message with a given computer, and pass it along to that computer to toggle the desired spawner.
 
  • Like
Reactions: EternalDensity

Hydra

New Member
Jul 29, 2019
1,869
0
0
You can actually have different bundled cables connected to different sides of a single computer, that way you can have more than 16. 5*16 would be the max that's feasable actually and since that's 80 different wires that should be enough for anything you want.
 

RavynousHunter

New Member
Jul 29, 2019
2,784
-3
1
You can actually have different bundled cables connected to different sides of a single computer, that way you can have more than 16. 5*16 would be the max that's feasable actually and since that's 80 different wires that should be enough for anything you want.

Aaaaah, I'd forgotten bout that! Okay, so fewer computers, and just a little alteration for routing to the proper side.

Isn't touch screen one of the main feature of the last Computer Craft update?

Yessir, I believe you are correct. Can only be done with advanced (gold) monitors, methinks.
 

Evil Hamster

New Member
Jul 29, 2019
768
0
0
Off topic, but do you know of a program that can make the display like the old windows 95/98 outer space screensaver?

The one where it made the screen look like it's traveling past stars.
 

Poppycocks

New Member
Jul 29, 2019
1,914
0
0
Off topic, but do you know of a program that can make the display like the old windows 95/98 outer space screensaver?

The one where it made the screen look like it's traveling past stars.
Shouldn't be too hard, will take a look tomorow, might be finished the day after that if business doesn't keep me.

On topic though, the touchscreen idea is great and I'm not trying to come up with a place where I could use it. Will use though.
 

Abdiel

New Member
Jul 29, 2019
1,062
0
0
Off topic, but do you know of a program that can make the display like the old windows 95/98 outer space screensaver?

The one where it made the screen look like it's traveling past stars.

I liked the idea, so here is my attempt: http://pastebin.com/4wy08KvF

This works on a monitor attached to the computer. So you can use it as a viewscreen for your spaceship.
 

Poppycocks

New Member
Jul 29, 2019
1,914
0
0
Do you mean my program? What error are you getting?
Oh no man, the buttons API.

Now that I'm reading it, it seems kinda unfinished. There's some glaring "I wrote this on paper, never ran" kinda errors as well, like using != instead of ~=.