Jump to content




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


  • You cannot reply to this topic
30 replies to this topic

#1 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

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.
Spoiler


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
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!

Posted Image

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!?

Posted Image

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

Posted Image

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>

#2 Sammich Lord

    IRC Addict

  • Members
  • 1,212 posts
  • LocationThe Sammich Kingdom

Posted 06 November 2012 - 11:01 PM

Nice code.

#3 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

Posted 07 November 2012 - 12:06 AM

View PostHuman, on 06 November 2012 - 11:01 PM, said:

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!

#4 Sammich Lord

    IRC Addict

  • Members
  • 1,212 posts
  • LocationThe Sammich Kingdom

Posted 07 November 2012 - 05:43 AM

View Postwraithbone, on 07 November 2012 - 12:06 AM, said:

View PostHuman, on 06 November 2012 - 11:01 PM, said:

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.

#5 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

Posted 07 November 2012 - 08:44 AM

View PostHuman, on 07 November 2012 - 05:43 AM, said:

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.

#6 anonimo182

  • Members
  • 252 posts
  • LocationIn the universe

Posted 07 November 2012 - 12:13 PM

Really nice and neat for future programs!

#7 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

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.

#8 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

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

#9 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

Posted 08 November 2012 - 05:33 PM

View Postreonrules1, on 08 November 2012 - 10:58 AM, said:

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.

#10 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 08 November 2012 - 10:37 PM

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

#11 Tiin57

    Java Lunatic

  • Members
  • 1,412 posts
  • LocationIndiana, United States

Posted 09 November 2012 - 06:23 AM

I suggest spoilers. :P/>

#12 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

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.

#13 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

Posted 09 November 2012 - 06:04 PM

View Postreonrules1, on 09 November 2012 - 02:56 PM, said:

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.

#14 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

Posted 09 November 2012 - 08:51 PM

View Posttiin57, on 09 November 2012 - 06:23 AM, said:

I suggest spoilers. :unsure:/>

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

View Postreonrules1, on 08 November 2012 - 10:37 PM, said:

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

Ouch...

#15 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 10 November 2012 - 02:35 PM

Ouch? Its semi true though. A lot of bad stuff comes out of auckland. particularily south.

#16 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

Posted 11 November 2012 - 01:29 PM

View Postreonrules1, on 10 November 2012 - 02:35 PM, said:

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

#17 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

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

#18 hedgehog1029

  • Members
  • 5 posts

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

#19 wraithbone

  • Members
  • 17 posts
  • LocationAuckland, New Zealand

Posted 10 December 2012 - 05:58 PM

View Posthedgehog1029, on 09 December 2012 - 10:14 PM, said:

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)


#20 MegaMech

  • Members
  • 12 posts

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]





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users