This repository was archived by the owner on Aug 18, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathProgressBar.scala
95 lines (82 loc) · 2.76 KB
/
ProgressBar.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import org.jline.terminal.TerminalBuilder
/**
* Progress bar used reporting the status while checking and downloading libs.
*
* @param max count of events e.g. length of the list which progress is monitored.
*/
class ProgressBar(max: Int) {
// Width of the terminal, used for size calculations
private val width = {
val width = TerminalBuilder.builder().dumb(true).build().getWidth
// Size couldn't be figured out, use a default
if (width <= 10)
80
else
width
}
private var count = 0
private var description = ""
// We need to create a empty line so that latest line before creation won't be overwritten by the draw method.
println()
draw() // Initial draw
/**
* Increases count by 1 and re-draws the progress bar with the updated count.
*/
def countUp(): Unit = {
// Thread-safeness when working with parallel collections
count.synchronized {
count += 1
draw()
}
}
/**
* Updates the description and re-draws the description line.
* @param desc the new description
*/
def updateDescription(desc: String): Unit = {
// Thread-safeness when working with parallel collections
description.synchronized {
description = desc
drawDescription()
}
}
/**
* Deletes the description to result in a blank line. The progress bar will still be visible.
* After this you can normally print at the beginning of a new line and don't start at the end of the description.
*/
def finish(): Unit = {
description = ""
drawDescription()
}
/**
* Draws the progress bar in the line above the current one.
*/
private def draw(): Unit = {
val barWidth = width - 16 // Width of the bar without percentage and counts
val percentage = count * 100 / max
val equalsSigns = "=" * (barWidth * percentage / 100)
val whiteSpaces = " " * (barWidth - equalsSigns.length)
val content = "%3d%% (%2d|%2d) [%s]".format(percentage, count, max, equalsSigns + ">" + whiteSpaces)
print(s"\033[1A\r$content\n")
// | | | |
// Go up 1 line | | |
// Go to beginning of line
// | |
// Actual progress bar
// |
// Go back down for description
}
/**
* Draws the description which is located in the current line.
*/
private def drawDescription(): Unit = {
// Cap the description at the width of the terminal, otherwise a new line is created and everything would shift.
// If the user needs to see a really long url he can just widen his terminal.
val content = description.take(width)
print(s"\r\033[0K$content")
// | |
// Go to beginning
// |
// Clear from cursor to end of the line
}
}