We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I have modified Processing's example Scrollbar/Slider class to be oriented vertically and have the slider start on top instead of the middle. The ratio of the slider's length to the scrollbar is the ratio of the maximum number of lines the text area can hold to the number of lines in the file. The scrollbar works perfectly in terms of moving the text along but their is one slight problem:
Upon opening relatively large files, the scrollbar goes too far, as in when the scrollbar reaches the end, the end of the document should be reached. However the scrollbar goes farther, with extra blank lines. The positioning of the text box could be off because I transferred the code from the text editor I am making.
The file I tested was 554 lines in length.
Here is the main file:
Scrollbar bar;
String content = "";
float scrollbarRatio;
String absolutePath;
int line;
void setup()
{
// Background and size
background(0);
size(int(displayWidth * 4/5), int(displayHeight * 4/5));
// Resizable Window
if (frame != null) {
frame.setResizable(true);
}
// Scrollbar
bar = new Scrollbar(width-12, 55, 24, height - 79, 1);
// Input
selectInput("Select a file to process:", "openFile");
}
// Create set of line numbers given starting number and number of lines
void createLineNumbers(int startingNumber, int numberOfLines)
{
textAlign(LEFT);
String lineText = "";
textLeading(22);
for (int i = startingNumber; i <= startingNumber + numberOfLines; i++)
{
lineText += (str(i) + "\n");
}
text(lineText, width/5 + 12.5, 75);
textAlign(CENTER);
}
void draw()
{
String[] adjustedLines = content.split("\n");
int maxLines = floor((height - 80) / 22);
if (adjustedLines.length > maxLines)
{
scrollbarRatio = ((float) maxLines) / ((float) adjustedLines.length);
}
// Text Box
fill(80);
rect(width/5, 55, width*4/5, height-55);
textAlign(LEFT);
textLeading(22);
fill(225);
String[] contentLines = content.split("\n");
String display = "";
int lineDifference = bar.getLineDifference();
if (adjustedLines.length > maxLines)
{
for (int i = lineDifference; i < maxLines + lineDifference; i++)
{
if (i < adjustedLines.length)
{
display += adjustedLines[i];
display += "\n";
}
}
} else
{
display = content;
}
text(display, width/5+55, 75);
fill(240);
if (maxLines < adjustedLines.length)
{
createLineNumbers(lineDifference, lineDifference + maxLines);
} else if (maxLines >= adjustedLines.length)
{
createLineNumbers(1, adjustedLines.length);
}
bar.resizeScrollbar(width-12, 55, 24, height - 79);
bar.update(scrollbarRatio);
bar.display(scrollbarRatio);
}
// File - Open
void openFile(File selection)
{
if (selection != null)
{
try
{
// Read content of file
absolutePath = selection.getAbsolutePath();
String lines[] = loadStrings(absolutePath);
// Reset content and line numbers
content = "";
line = 0;
for (int i = 0; i < lines.length; i++) {
String lineContent = lines[i] + "\n";
content += lineContent;
line++;
}
}
catch (Exception exc)
{
println(exc.getMessage());
}
}
}
And here is the Scrollbar class:
class Scrollbar
{
float swidth, sheight; // width and height of bar
float xpos, ypos; // x and y position of bar
float spos, newspos; // x position of slider
float sposMin, sposMax; // max and min values of slider
int loose; // how loose/heavy
boolean over; // is the mouse over the slider?
boolean locked; // is the mouse clicked over the slider
int lineDifference;
Scrollbar (int xp, int yp, int sw, int sh, int l) {
swidth = sw;
sheight = sh;
xpos = xp-swidth/2;
ypos = yp;
spos = ypos;
newspos = spos;
sposMin = ypos;
sposMax = ypos + sheight;
loose = l;
}
void resizeScrollbar(int xp, int yp, int sw, int sh)
{
xpos = xp - swidth/2;
ypos = yp;
swidth = sw;
sheight = sh;
}
void update(float ratio) {
if (over()) {
over = true;
} else {
over = false;
}
if (mousePressed && over) {
locked = true;
}
if (!mousePressed) {
locked = false;
}
if (locked) {
sposMax = ypos + sheight;
newspos = constrain(mouseY-swidth/2, sposMin, sposMax - sheight * ratio);
lineDifference = ceil((newspos - 55)/22 * (1/ratio));
if (abs(newspos - spos) > 1) {
spos = spos + (newspos-spos)/loose;
}
}
}
float constrain(float val, float minv, float maxv) {
return min(max(val, minv), maxv);
}
boolean over() {
if (mouseX > xpos && mouseX < xpos+swidth &&
mouseY > ypos && mouseY < ypos+sheight) {
return true;
} else {
return false;
}
}
void display(float ratio) {
fill(220);
rect(xpos, ypos, swidth, sheight);
if (over || locked) {
fill(80);
} else {
fill(190);
}
// Removes whitespace between slider and beginning of scrollbar
if (spos != 55 && floor(spos) == 55)
{
spos = 55;
}
// Removes whitespace between slider and end of scrollbar
if ((spos + sheight * ratio) != (sheight + ypos) && ceil(spos + sheight * ratio) == (sheight + ypos))
{
spos = sheight + ypos - (sheight * ratio);
}
rect(xpos, spos, swidth, sheight * ratio);
}
int getLineDifference()
{
return lineDifference;
}
}
Answers
http://forum.processing.org/two/discussion/11731/can-anybody-show-me-how-to-create-a-vertical-scrollbar
By first retrieving the line difference from the start when scrolled to the bottom of the page, adding it on to the maximum number of lines that could be stored in the area, and subtracting the length of the document, I got the extra amount that had to be subtracted from the denominator of the ratio.