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

How can I create a progress bar?

Started by minz1, 08 July 2016 - 03:07 PM
minz1 #1
Posted 08 July 2016 - 05:07 PM
I've been working on a reactor program that suits my needs. I've been working on a basic GUI, but I feel that to go further, I need interactive buttons and such, and a progress bar for the power. However, I couldn't figure out how a progress bar is made.

http://pastebin.com/Nu5kBxHH

That is my progam. Thanks for looking at my post.
Twijn #2
Posted 08 July 2016 - 05:18 PM
Try something similar to this:

divide the currentPower/maxPower. This should return a number 0-1, and it can be multiplied by 100 to get a percent. (basically you're just getting the percent and not multiplying it, though)

Take the number which is 0-1 and times it by the size of the progress bar. For example, if the size of it you wanted was 51 (the size of a computer), you would do 51*(number, 0-1), and floor it(math.floor) to get a whole number.

Draw a line (paintutils.drawLine) from the start of the progress bar to the start of the progress bar(-1?) + the whole number. You may have to subtract one form the start to make it work better, however that may involve a bit of testing. If you would like you may also make a line the size of the whole progress bar.
The Crazy Phoenix #3
Posted 08 July 2016 - 05:27 PM
Draw a line (paintutils.drawLine) from the start of the progress bar to the start of the progress bar(-1?) + the whole number. You may have to subtract one form the start to make it work better, however that may involve a bit of testing. If you would like you may also make a line the size of the whole progress bar.

You can easily draw a horizontal line without paintutils, just set the background colour to the colour of the line and term.write(" ") as many times as the line's length is in pixels.
minz1 #4
Posted 08 July 2016 - 06:24 PM
Draw a line (paintutils.drawLine) from the start of the progress bar to the start of the progress bar(-1?) + the whole number. You may have to subtract one form the start to make it work better, however that may involve a bit of testing. If you would like you may also make a line the size of the whole progress bar.

You can easily draw a horizontal line without paintutils, just set the background colour to the colour of the line and term.write(" ") as many times as the line's length is in pixels.
How would I got about using monitor.write(" ") multiple times without having a bunch of if statements?
Lemmmy #5
Posted 08 July 2016 - 06:24 PM

term.setBackgroundColour(colours.white)
term.write((" "):rep(math.floor(progress / maxProgress) * barWidth))
Edited on 08 July 2016 - 04:25 PM
minz1 #6
Posted 08 July 2016 - 07:01 PM
I'm having trouble implementing any of this. I don't know what's wrong, but Lemmmy's code doesn't display anything.
The Crazy Phoenix #7
Posted 09 July 2016 - 12:52 AM
I'm having trouble implementing any of this. I don't know what's wrong, but Lemmmy's code doesn't display anything.

Have you checked the background / foreground colours and the cursor position? term.write does not line-wrap the text (unlike write).
Bomb Bloke #8
Posted 09 July 2016 - 02:50 AM
I'm inclined to think you've rigged things such that math.floor(progress / maxProgress) * barWidth resolves to 0 (or perhaps <1).

Show us the code you used if you're still stuck.
PossieTV #9
Posted 09 July 2016 - 04:35 AM
I like to use a for loop for stuff like this. However you can use paintutils if you redirect to the monitor.

Like this
mon = peripheral.wrap(monSide) --Wraps the peripheral
oldTerm = term.redirect(mon) --Redirects the term while storing the old term in a variable named oldTerm
coloredPortion = math.floor((currentPower/maxPower) * width) --Calculates the width of the colored portion
paintutils.drawLine(startX, y, startX + width, y, barColor) --Draws the bar
paintutils.drawLine(startX,y,startX + coloredPortion, coloredPart) --Draws the colored portion over the bar
term.redirect(oldTerm) --Sets the term back to normal


However if you have an irrational aversion to paintutils like myself or you don't want to redirect the term, you can create your own draw line method like this

function drawLine(x,y,length,color) --Defines the function
  oldBgColor = term.getBackgroundColor() --Gets the current background color
  for i = x, (length + x) do --Starts a for loop starting at x and ending when x gets to x + length
	term.setCursorPos(i,y) --Set the cursor position to i,y
	term.setBackgroundColor(color) --Set the background color to the color
	term.write(" ") --Write that color to the screen
  end
  term.setBackgroundColor(oldBgColor) --Reset the background color
end


Of course should you decide to use this function you would have to tweak the first block of code. Just change the paintutils.drawLine() functions to this.

drawLine(startX, y, width, barColor) --Draws the bar
drawLine(startX, y, coloredPortion, coloredPart) --Draws the colored part over the bar

There you go, hope I could help.
minz1 #10
Posted 09 July 2016 - 06:32 AM
I like to use a for loop for stuff like this. However you can use paintutils if you redirect to the monitor.

Like this
mon = peripheral.wrap(monSide) --Wraps the peripheral
oldTerm = term.redirect(mon) --Redirects the term while storing the old term in a variable named oldTerm
coloredPortion = math.floor((currentPower/maxPower) * width) --Calculates the width of the colored portion
paintutils.drawLine(startX, y, startX + width, y, barColor) --Draws the bar
paintutils.drawLine(startX,y,startX + coloredPortion, coloredPart) --Draws the colored portion over the bar
term.redirect(oldTerm) --Sets the term back to normal


However if you have an irrational aversion to paintutils like myself or you don't want to redirect the term, you can create your own draw line method like this

function drawLine(x,y,length,color) --Defines the function
  oldBgColor = term.getBackgroundColor() --Gets the current background color
  for i = x, (length + x) do --Starts a for loop starting at x and ending when x gets to x + length
	term.setCursorPos(i,y) --Set the cursor position to i,y
	term.setBackgroundColor(color) --Set the background color to the color
	term.write(" ") --Write that color to the screen
  end
  term.setBackgroundColor(oldBgColor) --Reset the background color
end


Of course should you decide to use this function you would have to tweak the first block of code. Just change the paintutils.drawLine() functions to this.

drawLine(startX, y, width, barColor) --Draws the bar
drawLine(startX, y, coloredPortion, coloredPart) --Draws the colored part over the bar

There you go, hope I could help.
Thanks! What you said really helped me out. I'll take a closer look at what you posted to try to understand better. I tweaked the code a bit to fit what I'm doing.
http://pastebin.com/mj9TXeBu
Line 4 to line 10 is your drawline function, and line 58 to line 60 is the actual drawing of the line.
PossieTV #11
Posted 09 July 2016 - 07:01 AM
Glad I could help! Your implementation seems right so just let me know if you have any problems with it
Edited on 09 July 2016 - 05:40 AM
The Crazy Phoenix #12
Posted 10 July 2016 - 04:20 PM
I'm inclined to think you've rigged things such that math.floor(progress / maxProgress) * barWidth resolves to 0 (or perhaps &amp;lt;1). Show us the code you used if you're still stuck.

Actually I think Lemmmy performed the multiplication after the floor (instead of before), therefore the floor is always 0 unless if 100% is achieved.

I'm having trouble implementing any of this. I don't know what's wrong, but Lemmmy's code doesn't display anything.

Fixed code for a manual progress bar:


term.setBackgroundColour(colours.white)
term.write((" "):rep(math.floor(progress / maxProgress * barWidth)))
Edited on 10 July 2016 - 02:22 PM