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

User input?

Started by xXThunder607Xx, 20 February 2014 - 04:25 PM
xXThunder607Xx #1
Posted 20 February 2014 - 05:25 PM
Hi! Currently, I'm passing around the idea of making a ComputerCraft "operating-system". And I'm not too sure how to get input. I can do it with something like:



input = read()
  if input == "stuff" then
   some code
else
   some code
end

But this isn't very "interactive" so to speak. I would like to know how I could create a program where the user uses the arrow keys to move around an arrow, or something like that. For example:

Main menu
> Games
Rednet
Other

And the user would be able to move the ">" to select his/her choice. Sorry I'm not doing a good job at explaining, but this is the best I can explain it. If you could help me out, that would be great.

Thanks in advance :)/>
popdog15 #2
Posted 20 February 2014 - 06:32 PM
You could use grab keypresses using os.pullEvent("char") or pullEvent("key") and then if the key/character is an arrow key you can reprint the screen to whatever it should be. If you need me to explain it more, I can make some example code- just a bit tired at the moment. c:
CometWolf #3
Posted 20 February 2014 - 06:45 PM
Heres the function i use when i need arrow selection menues. It's pretty straight forward, and relies on pullEvent like popdog said.

function noColorInput(text,...)
  term.clear()
  term.setCursorPos(1,1)
  print(text) --print menu text
  local cursX,cursY = term.getCursorPos()
  local button = 1 --start selection
  local tButtons = {...}
  while true do
	for i=1,#tButtons do --render menu
	  local menuText = tButtons[i]
	  if button == i then
		menuText = "["..menuText.."]" -- render selection cursor
	  end
	  term.setCursorPos(1,cursY+i-1)
	  term.clearLine()
	  term.setCursorPos(tTerm.xMid-math.floor(#menuText/2),cursY+i-1) -- if you intend to copy my function, you'll have to replace tTerm.xMid with half the size of your screen.
	  term.write(menuText)
	end
	local _e,key = os.pullEvent"key" -- get key inputs
	if key == 28 then --enter
	  return tButtons[button]
	elseif key == 208 then --down arrow
	  button = button+1
	elseif key == 200 then --up arrow
	  button = button-1
	end
	if button > #tButtons then -- attempt to go below bottom selection
	  button = 1
	elseif button < 1 then -- attempt to go above top selection
	  button = #tButtons
	end
  end
end

noColorInput("Please pick a selection","selection1,"menu2","herpDerp")
Edited on 20 February 2014 - 05:47 PM
xXThunder607Xx #4
Posted 20 February 2014 - 07:25 PM
CometWolf, thanks for replying so fast! But Im not too sure what this is doing. Is there a way you could write me a program that would actually..well, work? I can use os.pullEvent("char") and that, but would I have to clear the screen every time I get an input? If you could make me one that would work with what I'm doing that would be awesome. EG:

Main Menu
> option1
option2
option3

Also, I copy'd this exactly and I don't know what you mean by replacing tTerm.xMid to half the size of my screen.
CometWolf #5
Posted 21 February 2014 - 12:14 AM
We're not here to make the program for you. I posted my function as an example, you should look through it and see how it works, as it's pretty simple. And ofcourse you'd have to clear the screen after making a selection. tTerm.xMid is the middel point of the screen on the x-axis. I assume you know how term.getSize works?
xXThunder607Xx #6
Posted 21 February 2014 - 11:26 AM
Yes, I'm quite familiar with it. The reason I asked you to make it work was that I didn't see the noColorInput() function hiding at the bottom. Sorry about that. If I detected an input, I could clear the screen and reprint the same "main menu" board, just with the arrow at the bottom?
If so, wouldn't you see the page clear, and a second later reappear? This would look a bit sloppy if that was the case.
Bomb Bloke #7
Posted 21 February 2014 - 07:25 PM
It depends how long you take in refreshing the screen. If you perform the clear and then immediately after print out the new display, then flicker should be minimal, assuming it can be seen at all. If you clear the display, perform a whole bunch of calculations and then redraw, yeah, you'll tend to get flicker.

Another option is to clear each line individually before re-writing (this is the approach Comet takes in the function he gave you), or devise a system where only those lines that're actually going to change get re-written, or one where you don't need to clear anything at all because everything's overwritten neatly…

Also take a look at the keys API. It enables you to write lines such as "elseif key == 208 then –down arrow" as just "elseif key == keys.down then", for eg.
CometWolf #8
Posted 21 February 2014 - 08:05 PM
Dunno how i didn't see that there was a new post in this topic, i swear the forum derps sometimes…

When you said "make a selection" i assumed you meant hitting enter, in which case i guessed you wanted something else to appear, so obviously you'd have to clear the screen. Either of the options bomb suggested should do the trick though.

I like to use the numbers instead of the keyes api, cause english isn't my main language. So the keyboard picture is much easier for me.:P/>