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

wraithbone's GUI (CLI really...) Functions

Started by wraithbone, 06 November 2012 - 08:11 PM
wraithbone #1
Posted 06 November 2012 - 09:11 PM
Ascii GUI (Text user interface) Functions

Note: There is a really good reason I don't just package these all up into a tidy API, because I want this code to be a learning experience for those who use it.

If you use my code and can't be bothered reading it (and you're probably not even reading this) that's fine!
If you do however use my code, modify it and make it better (that is not hard to do) then please post it back here for others to see and use. Share the code, we all learn stuff.

This is my thread from mccraftcpl copied across. Seeing as that forum doesn't get as much love as this one.

Here are some videos on using both general functions in LUA and my GUI functions too.
SpoilerFunctions
[media]http://www.youtube.com/watch?v=KYwivKJoIrw[/media]

GUI Functions
[media]http://www.youtube.com/watch?v=FwYkAlStg0A[/media]


Current List of Functions:
  • Loading Bar
  • Horizontal Selection Bar
  • Vertical Sliding bar
  • Vertical Menu
  • Key Pad
  • Message Box -new, advanced pc only
  • Check Boxes -new
  • Menu Bar -new, advanced pc only
  • Analogue Clock -new, please try to make it better




Loading Bar
Call the function with the parameters (start x, finish x, "<symbol>")

It will put a loading bar onto the next line. If the line is lower than the screen it will clear the screen and put the loading bar at the top.


function HorzLoadBar(sx, fx, sym)
x,y = term.getCursorPos()
if y >= 18 then
	term.clear()
	term.setCursorPos(sx,1)
	x,y = sx,1
end
term.setCursorPos(sx,y)
write("[")
term.setCursorPos(sx,y)
term.setCursorPos(fx-1,y)
write("]")
mdp = math.floor((sx + fx)/2) - 3
for i = (sx+1),(fx-2) do
	term.setCursorPos(i,y)
	write(sym)
	sleep(0.1) --CHANGE THIS TO EDIT TIME
	term.setCursorPos(mdp,y+1)
	write(string.format("%d",i/(fx-2) * 100))
	write("%")
end
term.setCursorPos(1,y+2)
end

Horizontal Selection Bar
This function creates a horizontal selection menu below the current line and the function returns the selected item as a string.
Parameters are:
(items for the menu as an LUA table, Y location you want the menu to appear)




function HorzMenu(menutable1, Ylocation)
	local selection1 = 1
	while true do
		term.setCursorPos(1, Ylocation)
		for i = 1,#menutable1 do
		  
			if i == selection1 then write"[" end
			write(menutable1[i])
			if i == selection1 then write"]" end
			write" | "
		  
		end
		local r,s = os.pullEvent()
	  
		if r == "key" then
			if s == 203 then selection1 = selection1 - 1 end
			if selection1 == 0 then selection1 = #menutable1 end
			if s == 205 then selection1 = selection1 + 1 end
			if selection1 == #menutable1 +1 then selection1 = 1 end
		  
			if s == 28 then
				term.setCursorPos(1,Ylocation + 1)
				return menutable1[selection1]
			end
		end
	  
	end
end


Vertical Sliding Bar
Select a numerical value by moving a slider up and down.
The max range of values is 14 atm. With a simple modification you can make it step in values.

Parameters are (start value, end value, Menu Title as string)


function vertBar(nMin, nMax, sTitle)
	local bSelected = false
	local selection = nMin
	local mdp = (nMin + math.floor((nMax - nMin)/2))
	if (nMax - nMin) > 13 then error("ERROR: Bar will not fit on screen max span is 14 e.g. 2 -> 15") end
	while (bSelected == false) do
		term.clear()
		term.setCursorPos(1,1)
		print(sTitle)
		print("[=]")
		for i = nMin,nMax do
			if i ~= selection then
				write" x"
				if i == mdp then
					print(" ", tostring(selection))
				else
					print("")
				end
			else
				write" -"
				if i == mdp then
					print(" ", tostring(selection))
				else
					print("")
				end		  
			end
		end
		print("[=]")
	  
		local ev1, ev2 = os.pullEvent()
	  
		if ev1 == "key" and ev2 ~= 28 then
			if selection <nmax then="" selection="selection" +="" 1="" else="" end="" elseif="" ev1="=" "key"="" and="" ev2="=" 28="" bselected="true" return(selection)


function VertMenu(tableofItems)
local selection = "";
local sIndex = 1;
while (selection == "") do
  term.clear();
  local xMax, yMax = term.getSize();
  local y = math.floor(yMax/2) + math.floor(#tableofItems/2);
  y = y - #tableofItems;
  if y<1 then y = 1 end;

  if #tableofItems > yMax then
   print "ERROR: List does not fit on screen, reduce number of items in table";
   return "";
  end

  for i = 1, #tableofItems do

  if string.len(tableofItems[i]) >= xMax then
   term.clear();
   term.setCursorPos(1,1);
   print (("ERROR: List item # "..i).." is too long please reduce");
   return "";
  end
   local x = math.floor(xMax/2) - math.floor(string.len(tableofItems[i])/2);

   if i == sIndex then x = x-1 end;
   term.setCursorPos(x,y);
   if i == sIndex then term.write("[") end;
   term.write(tableofItems[i]);

   if i == sIndex then term.write("]") end;

   y = y+1;
  end

  local r,s = os.pullEvent("key");

  if s == 208 then sIndex = sIndex +1 end;
  if s == 200 then sIndex = sIndex -1 end;
  if sIndex > #tableofItems then sIndex = 1 end;
  if sIndex < 1 then sIndex = #tableofItems end;
  if s == 28 then
	term.clear();
	term.setCursorPos(1,1);
	return tableofItems[sIndex]
  end
end
end
Due to demand here is some sample code for how to implement sub menus:
Spoiler

menu = {
	{"a","b","c"},
	{"d","e","f"},
	{"g","h","i"},
	{"j","k","l"},
	{"m","n","o"},
	{"p","q","r"}
}
results = {}
results[1] = VertMenu(menu[1])
if results[1] == "a" then
	results[2] = VertMenu(menu[2])
elseif results[1] == "b" then
	results[2] = VertMenu(menu[3])
elseif results[1] == "c" then
	results[2] = "Stop level 1"
end
if results[2] == "d" then
	results[3] = VertMenu(menu[4])
elseif results[2] == "e" then
	results[3] = VertMenu(menu[5])
elseif results[2] == "f" then
	results[3] = VertMenu(menu[6])
elseif results[2] == "g" then
	results[3] = "Stop level 2-1"
elseif results[2] == "h" then
	results[3] = "Stop level 2-2"
elseif results[2] == "i" then
	results[3] = "Stop level 2-3"
end
--if results[3]... --etc. etc. etc.
for a=1,#results do
	print(results[a])
end
Key Pad
Use this awesome keypad to get a 4 digit code from the user!
Gogo virtual hardware!

function: keyPad();
returns a table containing the 4 values in the order they were entered


function keyPad(void)
	local mt = {
			{1,2,3},
			{4,5,6},
			{7,8,9}
		 };
	local mt2 = {0,0,0,0};
	local xOffset = 23;
	local nX = 1;
	local nY = 1;
	local n = 1;
	while (n<=4) do
		term.clear();
		for i = 1,3 do
			for j = 1,3 do
				term.setCursorPos((xOffset + i),(j));
				if (nY == j) and (nX == i) then
					term.write("*");
				else
					term.write(mt[j][i]);
				end
			  
			end
		end
		for i = 1,n-1 do
			term.setCursorPos((xOffset + i),(4));
			term.write("*");
		end
		r,s = os.pullEvent();
	  
		if(r == "key") then
			if (s == 205) then
				if (nX < 3) then
					nX = nX +1;
				end
			end
			if (s == 208) then
				if (nY < 3) then
					nY = nY +1;
				end
			end
			if (s == 200) then
				if (nY > 1) then
					nY = nY - 1;
				end
			end
			if (s == 203) then
				if (nX > 1) then
					nX = nX -1;
				end
			end  
			if (s == 28) then
				mt2[n] = mt[nY][nX];
				n = n+1;
			end
		end
	end
	term.clear();
	term.setCursorPos((1),(1));
	return mt2;
end


1.4.6 Wohoo!

Here is some nice code to celebrate… a lovely message box.
Click on OK or X to close and the function will tell you what the user chose!
For advanced PCs only!



function is
drawMessageBox(startX,startY,sizeX,sizeY,message,title)

startX is the X position of the top left of the box
startY is the Y position of the top left of the box
size X is the width of the box
size Y is the height of the box
message is the line of text in the box
title is the text that appears in the top border


function drawMessageBox(bX,bY,bDX,bDY,message,title)

term.setCursorPos(bX,bY);


--Clear
term.setBackgroundColor(colors.white);
term.clear();
term.setBackgroundColor(colors.black);
term.setTextColor(colors.yellow);

--Print Box
for i = 0,bDY do
  term.setCursorPos(bX,bY+i);
  term.write(" ");
  term.setCursorPos(bX+bDX,bY+i);
  term.write(" ");
end -- for
for i = 1,bDX do
  if i == bDX then term.setBackgroundColor(colors.red) end
  term.setCursorPos(bX+i,bY);

  if i == bDX then term.write("X")else term.write(" "); end
  if i == bDX then term.setBackgroundColor(colors.black) end
  term.setCursorPos(bX+i,bY+bDY);
  term.write(" ");
end -- for

--Print Title
term.setCursorPos(bX,bY);
term.setTextColor(colors.white);
term.write(" "..title);

--Print Message
term.setBackgroundColor(colors.white);
term.setCursorPos(math.floor((bX+(bX+bDX))/2) - math.floor(#message/2),math.floor((bY+(bY+bDY))/2));
term.setTextColor(colors.blue);
term.write(message);

  --Print OK button
term.setBackgroundColor(colors.black);
term.setTextColor(colors.yellow);
term.setCursorPos(math.floor((bX+(bX+bDX))/2) - 2,bY+bDY);
term.write("[OK]");
term.setCursorPos(40,40);

--Listen for mouse and check where the user clicks
while(true)do
  a,MB,X,Y = os.pullEvent("mouse_click");

  XY = (X..",")..Y;--Convert click to cartesian Coords

  bDXY = ((bX+bDX)..",")..(bY); --Convert [X] location to cartesian coords

  if (XY == bDXY) then
   --Clear the screen
   term.setBackgroundColor(colors.black);
   term.setTextColor(colors.white);
   term.clear();
   term.setCursorPos(1,1);
   return "cancel"
  end
  okX = math.floor((bX+(bX+bDX))/2) - 2; --the [OK] location
  if(Y == (bY+bDY)) then
   if ((X >= okX) and (X<= okX +4)) then
	--Clear the screen
	term.setBackgroundColor(colors.black);
	term.setTextColor(colors.white);
	term.clear();
	term.setCursorPos(1,1);
	return "OK"
   end --if
  end -- if

end--while
end -- function
help = drawMessageBox(15,5,25,8,"Divide by 0","Error");
print (help);

Want some more 1.4.6 GUI goodness?
How about Check Boxes!?



function checkBoxes(items)

items - a table containing all the items in order that you want to be check box options

it returns a table containing true/false for each item

Scroll down for non-Advanced PC version

Advanced PC version: (uses mouse)


function checkBoxes(items)
	--Initialise the boolean (true/false) array
	state = {};
	for i = 1,#items do
		state[i] = false;
	end

	--Display the list and its boolean state
	while(true) do
		term.clear();
		term.setCursorPos(1,1);
		for i = 1,#items do
			if (state[i]) then
				term.write("[X] "); -- if active
			else
				term.write("[ ] "); -- if not
			end--if
			print(items[i]);
		end -- do
		print "[Done]"; -- Click this to finish
		e,mb,x,y = os.pullEvent("mouse_click");
		if(y==(#items + 1)) then return state end
		if(y<=#items) then state[y] = not state[y] end
	end -- while
	  
end -- function
this = checkBoxes({"One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve"});
for i = 1,#this do
	print(this[i]);
end

Standard PC Version (uses keyboard)




function checkBoxes(items)
	--Initialise the boolean (true/false) array
	state = {};
	for i = 1,#items do
		state[i] = false;
	end

	--Display the list and its boolean state
	counter = 1;
	while(true) do
		term.clear();
		term.setCursorPos(1,1);
		for i = 1,#items do
			if (state[i]) then
				term.write("[X] "); -- if active
			else
				term.write("[ ] "); -- if not
			end--if
		  
			if (i == counter) then
				term.write(items[i]);
				print "<";
			else
				print(items[i]);
			end
		end -- do
		if (counter == #items + 1) then print "[Done]<" else print "[Done]" end -- Select this to finish
	  
		e,k = os.pullEvent("key");
		if(k == 28 or k == 57 or k == 203 or k == 205) then
			if (counter == #items + 1) then
				return state
			else
				state[counter] = not state[counter];
			end
		end
		if(k == 208) then counter = counter + 1 end
		if(k == 200) then counter = counter - 1 end
		if(k == 209) then counter = counter + 5 end
		if(k == 201) then counter = counter - 5 end
		if (counter > #items + 1) then counter = 1 end
		if (counter < 1) then counter = #items + 1 end
	  
	end -- while
	  
end -- function
this = checkBoxes({"One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve"});
for i = 1,#this do
	print(this[i]);
end

Menu Bar
Like in MS Windows with the pull down menus



menuBar(items)

items is a table of tables (Yo dawg… I heard you like tables…), where the first item in each sub table is the title of the menu, and the subsequent entries are sub menu items.

Advanced PC only (uses mouse)



function menuBar(items)
itemIndex = 0;

while(true) do --forever
  --clear and reset terminal
  term.clear();
  term.setCursorPos(1,1);
  term.setCursorBlink(false);

  --Print the menu titles
  for i = 1, #items do
   term.write((items[i])[1] .. "  ");
  end
  --listen for mouse
  e,mb,x,y = os.pullEvent("mouse_click");
  --if they clicked on the menu
  if (y==1) then
   --stopValue is the graphical location at the end of the menu title the user will click on
   stopValue = 0;

   --loop through the items
   for i = 1,#items do
	--set the stop value to the end of the title string
	stopValue = stopValue + string.len( (items[i])[1] );
	--if it is between the stop value minus the word length and the stop value, then the user has clicked on a word
	if (x<=stopValue and x> (stopValue - string.len( (items[i])[1] ))) then
	 --set the index to what the user clicked on
	 itemIndex = i;
	 --break out the loop
	 break;
	end
	--allow for the double spacing bewteen items
	stopValue = stopValue +2;
   end

   --if the item index is greater than zero than the user has clicked on something
   if (itemIndex > 0) then

	--loop through the sub table
	for i = 2,#(items[itemIndex]) do
	 --line up to top item
	 term.setCursorPos((stopValue - string.len(items[itemIndex][1] )+1),i+1);
	 --print the sub menu
	 term.write(items[itemIndex][i]);
	
	end
	--listen for mouse again
	e2,mb2,x2,y2 = os.pullEvent("mouse_click");

	--if they clicked on something (and not in empty space on Y axis)

	if (y2 <= #(items[itemIndex]) + 2 and y2 ~= 1 and y2 ~= 2) then
	
	 --and not in empty space on X axis
	 if (x2 >= (stopValue-3) and x2 <= stopValue-3+(string.len(items[itemIndex][y2-1]))) then
	  --tidy up the screen and return the two items they clicked on.
	  term.clear();
	  term.setCursorPos(1,1);
	  return({items[itemIndex][1],items[itemIndex][y2-1]});
	 end
	end
   end
  end--if

end--while
end--function
n = menuBar({
{"Menu1","This","is","awesome"},
{"Menu2","This2","is2","awesome2"},
{"Menu3","This3","is3","awesome3"}
});
for i = 1,#n do
print(n[i]);
end

Analogue Clock

This is basically a radial meter that displays a needle at a certain percentage around the edge.

it takes two arguments the radius of the clock, and the percentage to display at this moment.
The example program is a simple time of day clock.
0 is at the top and 50% is at the bottom.

Advanced PC version (Pixel)


function drawCircle(r,timeperc)
--if you set the background and colors before calling the function
--and remove the term.clear()
--the clock will fill like a pie chart

term.setBackgroundColor(colors.white);
term.clear();
term.setBackgroundColor(colors.black);
term.setCursorBlink(false);

linedrawn = false;

sx,sy = term.getSize();
sx = math.floor(sx/2);
sy = math.floor(sy/2);

--These numbers are to do with the number of radians the algorithim needs to cycle through to draw a complete circle
--the offset is to make it start at the top of the screen

for i = 4.67,7.18 + 4.67,0.01 do

  --circle plotting alogrithim
  plotx = sx+1 + r*math.cos(i) *1.6;
  ploty = sy+1 + r*math.sin(i);

  term.setCursorPos(plotx,ploty);

  --I cant figure out why I need 1.88 instead of 2, be nice and help me with this...
  perc = timeperc/1.88;
  if(i > (4.67 + perc * (7.18 + 4.67)) and linedrawn == false) then
   drawLine({sx,sy},{plotx,ploty});
   linedrawn = true;
  end

  term.write(" ");

end
end
function drawLine(pt1,pt2)
p = pt2[1];
h = pt1[1];
q = pt2[2];
k = pt1[2];
for i = 0,1,0.01 do
  x = (p-h)*i + h;
  y = (q - k)*i + k;
  term.setCursorPos(x,y);
  term.write(" ");
end
end
term.redirect(peripheral.wrap("right"));
while(true)do
drawCircle(14,os.time()/24);
os.sleep(0.0001);--to stop jittering
end
term.setCursorPos(1,1);

Non-Advanced PC Version (ASCII)


function drawCircle(r,timeperc)
term.setCursorBlink(false);

linedrawn = false;

sx,sy = term.getSize();
sx = math.floor(sx/2);
sy = math.floor(sy/2);


for i = 4.67,7.18 + 4.67,0.01 do
  plotx = sx+1 + r*math.cos(i) *1.6;
  ploty = sy+1 + r*math.sin(i);

  term.setCursorPos(plotx,ploty);
  perc = timeperc/1.88;
  if(i > (4.67 + perc * (7.18 + 4.67)) and linedrawn == false) then
   drawLine({sx,sy},{plotx,ploty});
   linedrawn = true;
  end

  term.write("#");

end
end
function drawLine(pt1,pt2)
p = pt2[1];
h = pt1[1];
q = pt2[2];
k = pt1[2];
for i = 0,1,0.01 do
  x = (p-h)*i + h;
  y = (q - k)*i + k;
  term.setCursorPos(x,y);
  term.write("*");
end
end
--term.redirect(peripheral.wrap("right"));
while(true)do
drawCircle(8,os.time()/24);
os.sleep(0.0001);--to stop jittering

--if you remove the term.clear()
--the clock will fill like a pie chart
term.clear();
end
term.setCursorPos(1,1);
</nmax></symbol>
Sammich Lord #2
Posted 06 November 2012 - 11:01 PM
Nice code.
wraithbone #3
Posted 07 November 2012 - 12:06 AM
Nice code.
Thanks, it took me a while to put these together. Appreciate it.

On a side note I put up a new GUI item. Menu Bars!
Sammich Lord #4
Posted 07 November 2012 - 05:43 AM
Nice code.
Thanks, it took me a while to put these together. Appreciate it.

On a side note I put up a new GUI item. Menu Bars!
I actually have some very nice code for a mouse GUI. You give each button some properties that can be changed at anytime during the program. For instance: If I click a button it runs a function that makes another button visible.
wraithbone #5
Posted 07 November 2012 - 08:44 AM
I actually have some very nice code for a mouse GUI. You give each button some properties that can be changed at anytime during the program. For instance: If I click a button it runs a function that makes another button visible.

Ahh I see. That sounds very visual studio-esque.
anonimo182 #6
Posted 07 November 2012 - 12:13 PM
Really nice and neat for future programs!
wraithbone #7
Posted 07 November 2012 - 04:46 PM
I put up the analogue clock program. It's really unpolished, but it works… some input on it would be great.
Kryptanyte #8
Posted 08 November 2012 - 10:58 AM
Nice to see you have moved over Wraith. Always found your code useful and easy to learn from. Except the Vertical Menu. I havent got to math yet =s
wraithbone #9
Posted 08 November 2012 - 05:33 PM
Nice to see you have moved over Wraith. Always found your code useful and easy to learn from. Except the Vertical Menu. I havent got to math yet =s

Math, eh? Well then don't look at the code for the analogue clock.
Kryptanyte #10
Posted 08 November 2012 - 10:37 PM
Lol. Well at least something good came out of Auckland eh?
Tiin57 #11
Posted 09 November 2012 - 06:23 AM
I suggest spoilers. :P/>/>
Kryptanyte #12
Posted 09 November 2012 - 02:56 PM
One thing wraithbone. With your vertical menu, when you have an item selected shouldn't it keep the text in the same place and put the box around the text.

Like it takes 1 off the x location of the table item that is selected then puts the box around it.

Not sure if its a glitch in the code or you haven't put it in. But when selecting down the list it looks odd having the text move one to the right.
wraithbone #13
Posted 09 November 2012 - 06:04 PM
One thing wraithbone. With your vertical menu, when you have an item selected shouldn't it keep the text in the same place and put the box around the text.

Like it takes 1 off the x location of the table item that is selected then puts the box around it.

Not sure if its a glitch in the code or you haven't put it in. But when selecting down the list it looks odd having the text move one to the right.

Ahh good spotting there, indeed.

I have corrected the program. The line in question was:

  term.setCursorPos(x,y);
  if i == sIndex then x = x-1 end;
  if i == sIndex then term.write("[") end;
and it should have been:

  if i == sIndex then x = x-1 end;
  term.setCursorPos(x,y);
  if i == sIndex then term.write("[") end;

The reason for this x shift is because the [ is appended to the front of the line, making it one character longer. This means the line has to be shifted back one to fit centred.
wraithbone #14
Posted 09 November 2012 - 08:51 PM
I suggest spoilers. :unsure:/>/>

I tried but it screws up all the code blocks….

Lol. Well at least something good came out of Auckland eh?

Ouch…
Kryptanyte #15
Posted 10 November 2012 - 02:35 PM
Ouch? Its semi true though. A lot of bad stuff comes out of auckland. particularily south.
wraithbone #16
Posted 11 November 2012 - 01:29 PM
Ouch? Its semi true though. A lot of bad stuff comes out of auckland. particularily south.
Well I'm up on the North Shore, so I'm about 20km and a harbour brigde safer than the rest. =P
Kryptanyte #17
Posted 11 November 2012 - 11:26 PM
Lucky. See here I sit in Rotovegas. Chilling with no accomplishments what so ever xD. Thats a point. What good came out of my city =S Lol
hedgehog1029 #18
Posted 09 December 2012 - 10:14 PM
um… with the vertical menu, where does the table of items go? im noobish with this complex stuff :P/>
wraithbone #19
Posted 10 December 2012 - 05:58 PM
um… with the vertical menu, where does the table of items go? im noobish with this complex stuff :P/>

copy and paste the function into the top of the code. underneath it write:


table1 = {"One", "Two", "Three"} --defines the first table
table2 = {"A", "B", "C", "D", "E", "F"} --defines the second table
ans1 = VertMenu(table1) --calls the function with the first table
ans2 = VertMenu(table2) --calls the function with the second table
print("First Choice: " + ans1) -- print both answers
print("Second Choice: " + ans2)
MegaMech #20
Posted 22 December 2012 - 06:59 AM
I can't figure out the table for VertMenu()
I think you should add a bit more instructions to your post.
Otherwise, this is pretty cool, and looks clean… I'm probably gonna use it for a Stats Program I'm making. (Shows the status of all your industry's stuff)


table={"all","my","stuff"}
table2={"in","here","done"}
result = VertMenu(table)
result2 = Vertmenu(table2)
This makes it so if you select anything from table it shows everything from table2
how do I make it so if I choose "all" It shows table2 and if I choose "my" it shows everything from table3
or
if I choose "all" it shows table2[1] and if I choose "my" it shows table2[2]
wraithbone #21
Posted 20 January 2013 - 12:09 AM
I can't figure out the table for VertMenu()
I think you should add a bit more instructions to your post.
Otherwise, this is pretty cool, and looks clean… I'm probably gonna use it for a Stats Program I'm making. (Shows the status of all your industry's stuff)


table={"all","my","stuff"}
table2={"in","here","done"}
result = VertMenu(table)
result2 = Vertmenu(table2)
This makes it so if you select anything from table it shows everything from table2
how do I make it so if I choose "all" It shows table2 and if I choose "my" it shows everything from table3
or
if I choose "all" it shows table2[1] and if I choose "my" it shows table2[2]

You make use of an if statement

result = {}
if result[1] == this then
	result[2] = something
  
elseif result[1] == that then
	result[2] = something_else
  
elseif result[1] == other then
	result[2] = another_thing
  
end
if result[2] == even then
	result[3] = something_again
  
elseif result[2] == more then
	result[3] = something_new
  
elseif result[2] == things then
	result[3] = another_thing_entirely
  
end
--and so on and so forth....

Instead of making the result table equal to those made up variables, you can call the menu function to generate sub menus.

EDIT: In fact I get this question so often I have put some sample code under the VertMenu section (in a spoiler) to show how this might be done.
pivotdude #22
Posted 31 May 2013 - 03:45 AM
hey im trying to get the load bar to work on startup alongside my user login screen but i keep getting the following error :
bios:338: [string "startup"} :19: "=" expected

Here is my code

[CODE]
print("Prototype OS V0.01")
write("Login: ")
lanswer = read()
if lanswer == "Pivotdude" then
write("Password: ")
else
os.reboot()
end
panswer = read()
if panswer == "1337" then
print("Welcome "..lanswer..".")
else
os.reboot()
end
term.clear()
function HorzLoadBar(sx, fx, sym)
start x, finish x, "<symbol>"
end
function HorzLoadBar(sx, fx, sym)
x,y = term.getCursorPos()
if y >= 18 then
term.clear()
term.setCursorPos(sx,1)
x,y = sx,1
end
term.setCursorPos(sx,y)
write("[")
term.setCursorPos(sx,y)
term.setCursorPos(fx-1,y)
write("]")
mdp = math.floor((sx + fx)/2) - 3
for i = (sx+1),(fx-2) do
term.setCursorPos(i,y)
write(sym)
sleep(0.1) –CHANGE THIS TO EDIT TIME
term.setCursorPos(mdp,y+1)
write(string.format("%d",i/(fx-2) * 100))
write("%")
end
term.setCursorPos(1,y+2)
end


EDIT: i am using the standard non advanced computer , should i be using the golden advanced one?
EDIT II: if i use brackets around the command in the function permameter its the same error except from the fact that ) is expected instead of =
Tjakka5 #23
Posted 31 May 2013 - 03:09 PM

print("Prototype OS V0.01")
write("Login: ")
lanswer = read()
if lanswer == "Pivotdude" then
write("Password: ")
else
os.reboot()
end
panswer = read()
if panswer == "1337" then
print("Welcome "..lanswer..".")
else
os.reboot()
end
term.clear()
function HorzLoadBar(sx, fx, sym)
x,y = term.getCursorPos()
if y >= 18 then
		term.clear()
		term.setCursorPos(sx,1)
		x,y = sx,1
end
term.setCursorPos(sx,y)
write("[")
term.setCursorPos(sx,y)
term.setCursorPos(fx-1,y)
write("]")
mdp = math.floor((sx + fx)/2) - 3
for i = (sx+1),(fx-2) do
		term.setCursorPos(i,y)
		write(sym)
		sleep(0.1) --CHANGE THIS TO EDIT TIME
		term.setCursorPos(mdp,y+1)
		write(string.format("%d",i/(fx-2) * 100))
		write("%")
end
term.setCursorPos(1,y+2)
end

Try something like this, I dont have the time to test if it works now, but I noted that the function 'HorLoadBar' was in there twice, the 1 one causing the error.
jesusthekiller #24
Posted 31 May 2013 - 07:16 PM
You don't say TUI…

You say CLI (Console Line Interface).
But even if you are using ASCII, it's still GUI.
pivotdude #25
Posted 01 June 2013 - 02:20 PM
Okay so i fixed it but i wanted to point out that i have not a single clue on what im doing since im new to CC however how would i center the login and the loadbar? i tried a general center function but it contradicts the other lines of code with multiple quoted brackets and stuff. also i am using notepad ++ to code (screw rewriting code - i did however do the loadbar 100% in CC prior to realising np++ read CC programs which can be seen by my mistake in the code)
pivotdude #26
Posted 03 June 2013 - 12:03 PM
I am sorry for double posting , but i am trying to get the windows style menu to work along side your loadbar and my login and system time on startup , i dont error but it refuses to show time and the menu (prepare for lots of code)

Loadbar:
Spoiler

print("PTOS V0.1.2")

print("loading PTOS Core System Files And Settings")
function HorzLoadBar(sx, fx, sym)
x,y =term.getCursorPos()
if y >= 18 then
term.clear()
term.setCursorPos(sx,1)
x,y = sx,1
end
term.setCursorPos(sx,y)
write("[")
term.setCursorPos(sx,y)
term.setCursorPos(fx-1,y)
write("]")
mdp = math.floor((sx + fx)/2) - 3
for i = (sx+1),(fx-2) do
term.setCursorPos(i,y)
write(sym)
sleep(0.1)
term.setCursorPos(mdp,y+1)
write(string.format("%d",i/(fx-2) * 100))
write("%")
end
term.setCursorPos(1,y+2)
end
HorzLoadBar(15,35,"|")
term.clear()

Login:
Spoiler

print("PTOS V0.1.2")
write("Login: ")
lanswer = read()
if lanswer == "Pivotdude" then
write("Password: ")
else
os.reboot()
end
panswer = read("*")
if panswer == "1337" then
print("Welcome "..lanswer..".")
else
os.reboot()
end
term.clear()

System Clock:
Spoiler

print(textutils.formatTime(os.time(), false))

Windows style menu:
Spoiler

function VertMenu(tableofItems)
local selection = "";
local sIndex = 1;
while (selection == "") do
  term.clear();
  local xMax, yMax = term.getSize();
  local y = math.floor(yMax/2) + math.floor(#tableofItems/2);
  y = y - #tableofItems;
  if y<1 then y = 1 end;
  if #tableofItems > yMax then
   print "ERROR: List does not fit on screen, reduce number of items in table";
   return "";
  end
  for i = 1, #tableofItems do
  if string.len(tableofItems[i]) >= xMax then
   term.clear();
   term.setCursorPos(1,1);
   print (("ERROR: List item # "..i).." is too long please reduce");
   return "";
  end
   local x = math.floor(xMax/2) - math.floor(string.len(tableofItems[i])/2);

   if i == sIndex then x = x-1 end;
   term.setCursorPos(x,y);
   if i == sIndex then term.write("[") end;
   term.write(tableofItems[i]);

   if i == sIndex then term.write("]") end;

   y = y+1;
  end
  local r,s = os.pullEvent("key");
  if s == 208 then sIndex = sIndex +1 end;
  if s == 200 then sIndex = sIndex -1 end;
  if sIndex > #tableofItems then sIndex = 1 end;
  if sIndex < 1 then sIndex = #tableofItems end;
  if s == 28 then
	    term.clear();
	    term.setCursorPos(1,1);
	    return tableofItems[sIndex]
  end
end
end

Startup:
Spoiler

shell.run("loadbar")
shell.run("login")
term.clear
shell.run("menu")
shell.run("systemtime")

could someone please point ou what im doing wrong
wraithbone #27
Posted 27 June 2013 - 12:53 AM
You don't say TUI…

You say CLI (Console Line Interface).
But even if you are using ASCII, it's still GUI.
Thanks, I have changed the description.
Love the OP-Amp Avatar. =)
We all know that positive feedback just makes you unstable.

I am sorry for double posting , but i am trying to get the windows style menu to work along side your loadbar and my login and system time on startup , i dont error but it refuses to show time and the menu (prepare for lots of code)
<ABBREVIATED>
could someone please point ou what im doing wrong

Let me have a look.
jesusthekiller #28
Posted 27 June 2013 - 12:50 PM
You googled it up or you already knew? :D/>
Dave-ee Jones #29
Posted 03 July 2013 - 05:43 AM
Nice. Love the message box!
wraithbone #30
Posted 03 July 2013 - 06:20 AM
You googled it up or you already knew? :D/>

Sadly enough I already knew. One of the side affects of being an electrical engineer.

Nice. Love the message box!

Thanks. Hope this makes your programs look good.
wraithbone #31
Posted 03 July 2013 - 06:25 AM
I am sorry for double posting , but i am trying to get the windows style menu to work along side your loadbar and my login and system time on startup , i dont error but it refuses to show time and the menu (prepare for lots of code)


Windows style menu:
Spoiler

function VertMenu(tableofItems)
local selection = "";
local sIndex = 1;
while (selection == "") do
  term.clear();
  local xMax, yMax = term.getSize();
  local y = math.floor(yMax/2) + math.floor(#tableofItems/2);
  y = y - #tableofItems;
  if y<1 then y = 1 end;
  if #tableofItems > yMax then
   print "ERROR: List does not fit on screen, reduce number of items in table";
   return "";
  end
  for i = 1, #tableofItems do
  if string.len(tableofItems[i]) >= xMax then
   term.clear();
   term.setCursorPos(1,1);
   print (("ERROR: List item # "..i).." is too long please reduce");
   return "";
  end
   local x = math.floor(xMax/2) - math.floor(string.len(tableofItems[i])/2);

   if i == sIndex then x = x-1 end;
   term.setCursorPos(x,y);
   if i == sIndex then term.write("[") end;
   term.write(tableofItems[i]);

   if i == sIndex then term.write("]") end;

   y = y+1;
  end
  local r,s = os.pullEvent("key");
  if s == 208 then sIndex = sIndex +1 end;
  if s == 200 then sIndex = sIndex -1 end;
  if sIndex > #tableofItems then sIndex = 1 end;
  if sIndex < 1 then sIndex = #tableofItems end;
  if s == 28 then
		term.clear();
		term.setCursorPos(1,1);
		return tableofItems[sIndex]
  end
end
end

could someone please point ou what im doing wrong

As far as I can tell the only thing that is missing here is that your menu program does not actually do anything. The function is there but you don't call it, or pass it anything.