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

Help With Write

Started by mrdawgza, 30 October 2013 - 05:27 AM
mrdawgza #1
Posted 30 October 2013 - 06:27 AM
Hello, I need help for my OS.

I've tried this many different ways,
I have a clickable UI, and say on the login screen I have
write("Username:") 
But what about when I don't want to login,
How can I make it do write and also listen for a click on an exit button?

If it's simple - I'm stupid
sens #2
Posted 30 October 2013 - 06:42 AM
write() is simply displaying "Username: " on the screen, it's not waiting for any user input. Would you post the part of the program that reads the username typed by the user?
mrdawgza #3
Posted 30 October 2013 - 06:59 AM
write() is simply displaying "Username: " on the screen, it's not waiting for any user input. Would you post the part of the program that reads the username typed by the user?

Nono, I have that already I was just on my iPad.

I currently have to read the input:


write("Username: ")
username = read()

write("Password: ")
password = read()

user.logIn(username, password) --user.logIn is an API in my functions program
sens #4
Posted 30 October 2013 - 07:41 AM
You could replace the calls to read() with a function that handles other events as well. 100% untested, just to give you an idea:


local function handleInputField(isPassword)
  isPassword = isPassword or false
  local buffer=""
  while true do
	local event, result, x, y = os.pullEvent()
	if event=="mouse_click" and withinCancelButton(x, y) then
	  return nil  --# Cancel button clicked
	elseif event=="key" then
	  if result == keys.enter then
		break  --#Submit the current buffer
	  elseif result == keys.backspace and string.len(buffer) > 0 then
		--# Remove the last character in buffer
		buffer = string.sub(buffer, 1, -2)
		backspace()
	  end
	elseif event == "char" then
	  --# Append the char to the buffer
	  buffer = buffer..result
	  if isPassword then
		write("*")
	  else
		write(result)
	  end
	end
  end
  return buffer
end
local function backspace()
  local x, y = term.getCursorPos()
  term.setCursorPos(x - 1, y)
  write(" ")
  term.setCursorPos(x - 1, y)
end

By the way, does anyone else find that the CODE tags don't do well with tab indentation? Space indenting seems to be fine.
mrdawgza #5
Posted 30 October 2013 - 08:05 AM
I'll look at it now, I'm not at home.
whatxDxDxD #6
Posted 30 October 2013 - 05:16 PM
I think you could also use the parallel API: http://computercraft.info/wiki/Parallel_(API)
spdkils #7
Posted 30 October 2013 - 05:31 PM
I wrote a rudementry OS for turtles, and I had to basically run the program with an event loop, and just respond to events the whole time.

So, keystrokes can be caught and handled, or you can just take 'normal' textual input, and move the program along based on input strings.
TheOddByte #8
Posted 01 November 2013 - 12:32 PM
The best way todo this would be to have a modified reading function ( as mentioned above ), This isn't exactly very hard.
You know how to use events right?
Here's an simple reading function

local function mRead()
	local str = ""
	while true do
		term.clear() term.setCursorPos(1,1)
		term.write(str)
		local evt, p1. mX. mY = os.pullEvent()

		if evt == "char" then
			str = str..p1 --# Adding a letter to the text

		elseif evt == "key" then
			if p1 == 28 then --# Exiting and returning the text inputted
				return str
			elseif p1 == 14 then
				str = string.sub(str,1,#str - 1) --# Removing a char when backspace have been pressed
			end

		elseif evt == "mouse_click" then
			-- Your code here for the button or whatever.
		end
	end
end

This is just a simple example, But that's pretty much a way todo it.
IMO parallel tend to cause flickering/lag if not properly used and this is a lot simpler.
nutcase84 #9
Posted 01 November 2013 - 02:51 PM
The best way todo this would be to have a modified reading function ( as mentioned above ), This isn't exactly very hard.
You know how to use events right?
Here's an simple reading function

local function mRead()
	local str = ""
	while true do
		term.clear() term.setCursorPos(1,1)
		term.write(str)
		local evt, p1. mX. mY = os.pullEvent()

		if evt == "char" then
			str = str..p1 --# Adding a letter to the text

		elseif evt == "key" then
			if p1 == 28 then --# Exiting and returning the text inputted
				return str
			elseif p1 == 14 then
				str = string.sub(str,1,#str - 1) --# Removing a char when backspace have been pressed
			end

		elseif evt == "mouse_click" then
			-- Your code here for the button or whatever.
		end
	end
end

This is just a simple example, But that's pretty much a way todo it.
IMO parallel tend to cause flickering/lag if not properly used and this is a lot simpler.

Dude, your making noobs scratch there heads.
mrdawgza #10
Posted 01 November 2013 - 03:08 PM
The best way todo this would be to have a modified reading function ( as mentioned above ), This isn't exactly very hard.
You know how to use events right?
Here's an simple reading function

local function mRead()
	local str = ""
	while true do
		term.clear() term.setCursorPos(1,1)
		term.write(str)
		local evt, p1. mX. mY = os.pullEvent()

		if evt == "char" then
			str = str..p1 --# Adding a letter to the text

		elseif evt == "key" then
			if p1 == 28 then --# Exiting and returning the text inputted
				return str
			elseif p1 == 14 then
				str = string.sub(str,1,#str - 1) --# Removing a char when backspace have been pressed
			end

		elseif evt == "mouse_click" then
			-- Your code here for the button or whatever.
		end
	end
end

This is just a simple example, But that's pretty much a way todo it.
IMO parallel tend to cause flickering/lag if not properly used and this is a lot simpler.
I do quite understand events, that code looks a little, ehum, confusing… Not because it's bad, just because either I'm not in the mood to program or tired, or confusing…
Although I got it working with the parallel API.. (Thanks LBPHacker, again…)
Thank you everyone for helping me/showing suggestions on how to do this…
ElvishJerricco #11
Posted 01 November 2013 - 04:49 PM
The easiest way is to use parallel.


local loggedIn = false
parallel.waitForAny(function()
    write("Username: ")
    username = read()

    write("Password: ")
    password = read()

    loggedIn = true
    user.logIn(username, password) --user.logIn is an API in my functions program
end, function()
    someButtonApi.waitForButtonPress()
    loggedIn = false
end)

if loggedIn then
    -- ...
else
    -- ...
end

Just be sure that the code for buttons always returns the cursor to the position it was at before it moved it. Not quite sure how read() works but I imagine they might collide.