I did the same as the poster above, modified the Topic - GUI - Scrollbar example to my own use. I guess that example is very simple by design to get people going and improve it. Still I just thought I'd offer my version, and also a slightly modified Buttons class, with a clicked() method. Not perfect but it works.
The scrollbar class is really a slider, but the name stuck from the example, for now at least. It returns or set a float value from 0 to 1.
I know it's an old thread, but I was planning to post this anyway, and might as well do it in a related place. Also, this was basically made before I knew about the controlP5 library (and which I don't really understand much of). ControlP5 also contains a lot more.
Anyway, the scrollbar and buttons classes:
- /** Horizontal scrollbar
A sightly improved Hscrollbar class
- Returns or sets a float value from 0 - 1
Built on Topics/GUI/Scrollbar example in processing 1.2.1 (and 1.5.1).
Ok, scrollbars are not really scrollbars, but sliders (setting/getting values).
(But they could theoretically be used as scrollbars...)
*/
class HScrollbar
{
int barWidth, barHeight; // width and height of bar. NOTE: barHeight also used as slider button width.
int Xpos, Ypos; // upper-left position of bar
float Spos, newSpos; // x (leftmost) position of slider
int SposMin, SposMax; // max and min values of slider
int loose; // how loose/heavy
boolean over; // True if hovering over the scrollbar
boolean locked; // True if a mouse button is pressed while on the scrollbar
color barOutlineCol;
color barFillCol;
color barHoverCol;
color sliderFillCol;
color sliderPressCol;
HScrollbar (int X_start, int Y_start, int bar_width, int bar_height, int loosiness,
color bar_outline, color bar_background, color slider_bg, color barHover, color slider_press) {
barWidth = bar_width;
barHeight = bar_height;
Xpos = X_start;
Ypos = Y_start;
Spos = Xpos + barWidth/2 - barHeight/2; // center it initially
newSpos = Spos;
SposMin = Xpos;
SposMax = Xpos + barWidth - barHeight;
loose = loosiness;
if (loose < 1) loose = 1;
barOutlineCol = bar_outline;
barFillCol = bar_background;
sliderFillCol = slider_bg;
barHoverCol = barHover;
sliderPressCol = slider_press;
}
void update() {
over = over();
if(mousePressed && over) locked = true; else locked = false;
if(locked) {
newSpos = constrain(mouseX-barHeight/2, SposMin, SposMax);
}
if(abs(newSpos - Spos) > 0) {
Spos = Spos + (newSpos-Spos)/loose;
}
}
int constrain(int val, int minv, int maxv) {
return min(max(val, minv), maxv);
}
boolean over() {
if(mouseX > Xpos && mouseX < Xpos+barWidth &&
mouseY > Ypos && mouseY < Ypos+barHeight) {
return true;
} else {
return false;
}
}
void display() {
stroke(barOutlineCol);
fill(barFillCol);
rect(Xpos, Ypos, barWidth, barHeight);
if(over) {
fill(barHoverCol);
}
if (locked) {
fill(sliderPressCol);
}
if (!over && !locked) {
fill (sliderFillCol);
}
if (abs(Spos-newSpos)>0.1) fill (sliderPressCol);
rect(Spos, Ypos, barHeight, barHeight);
}
float value() {
// Convert slider position Spos to a value between 0 and 1
return (Spos-Xpos) / (barWidth-barHeight);
}
void setValue(float value)
{
// convert a value (0 to 1) to slider position
if (value<0) value=0;
if (value>1) value=1;
Spos = Xpos + ((barWidth-barHeight)*value);
newSpos = Spos;
}
}
/** Vertical scrollbar
Modified from Hscrollbar class
Returns or sets a float value from 0 - 1
*/
class VScrollbar
{
int barWidth, barHeight; // width and height of bar. NOTE: barWidth also used as slider button height.
int Xpos, Ypos; // upper-left position of bar
float Spos, newSpos; // y (upper) position of slider
int SposMin, SposMax; // max and min values of slider
int loose; // how loose/heavy
boolean over; // True if hovering over the scrollbar
boolean locked; // True if a mouse button is pressed while on the scrollbar
color barOutlineCol;
color barFillCol;
color barHoverCol;
color sliderFillCol;
color sliderPressCol;
VScrollbar (int X_start, int Y_start, int bar_width, int bar_height, int loosiness,
color bar_outline, color bar_background, color slider_bg, color barHover, color slider_press) {
barWidth = bar_width;
barHeight = bar_height;
Xpos = X_start;
Ypos = Y_start;
Spos = Ypos + barHeight/2 - barWidth/2; // center it initially
newSpos = Spos;
SposMin = Ypos;
SposMax = Ypos + barHeight - barWidth;
loose = loosiness;
if (loose < 1) loose = 1;
barOutlineCol = bar_outline;
barFillCol = bar_background;
sliderFillCol = slider_bg;
barHoverCol = barHover;
sliderPressCol = slider_press;
}
void update() {
over = over();
if(mousePressed && over) locked = true; else locked = false;
if(locked) {
newSpos = constrain(mouseY-barWidth/2, SposMin, SposMax);
}
if(abs(newSpos - Spos) > 0) {
Spos = Spos + (newSpos-Spos)/loose;
}
}
int constrain(int val, int minv, int maxv) {
return min(max(val, minv), maxv);
}
boolean over() {
if(mouseX > Xpos && mouseX < Xpos+barWidth &&
mouseY > Ypos && mouseY < Ypos+barHeight) {
return true;
} else {
return false;
}
}
void display() {
stroke(barOutlineCol);
fill(barFillCol);
rect(Xpos, Ypos, barWidth, barHeight);
if(over) {
fill(barHoverCol);
}
if (locked) {
fill(sliderPressCol);
}
if (!over && !locked) {
fill (sliderFillCol);
}
if (abs(Spos-newSpos)>0.1) fill (sliderPressCol);
rect(Xpos, Spos, barWidth, barWidth);
}
float value() {
// Convert slider position Spos to a value between 0 and 1
return (Spos-Ypos) / (barHeight-barWidth);
}
void setValue(float value) {
// convert a value (0 to 1) to slider position Spos
if (value<0) value=0;
if (value>1) value=1;
Spos = Ypos + ((barHeight-barWidth)*value);
newSpos = Spos;
}
}
/** Button class
Slightly modified from processing 1.2.1 Buttons class example
*/
class Button
{
int x, y;
int size;
color edgeCol, baseColor, highlightColor;
color hoverColor, currentColor;
boolean pressed = false;
boolean oldPressed = false;
boolean outsidePressed = false;
void update()
{
if(over()) {
currentColor = hoverColor;
if (mousePressed && !oldPressed && !outsidePressed) {
pressed = true;
currentColor = highlightColor;
}
if (!mousePressed) {
oldPressed = pressed;
pressed = false;
outsidePressed = false;
}
} else {
currentColor = baseColor;
pressed = false;
outsidePressed = mousePressed;
}
}
boolean pressed() {
return pressed;
}
boolean clicked() {
return oldPressed;
}
boolean over() {
return false;
}
}
class CircleButton extends Button
{
CircleButton(int ix, int iy, int isize, color edColor, color iColor, color iHover, color iHighlight) {
x = ix;
y = iy;
size = isize;
edgeCol = edColor;
baseColor = iColor;
hoverColor = iHover;
highlightColor = iHighlight;
currentColor = baseColor;
}
boolean over() {
float disX = x - mouseX;
float disY = y - mouseY;
if(sqrt(sq(disX) + sq(disY)) < size/2 ) {
return true;
} else return false;
}
void display() {
stroke(edgeCol);
fill(currentColor);
ellipse(x, y, size, size);
}
}
class RectButton extends Button
{
RectButton(int ix, int iy, int isize, color edColor, color iColor, color iHover, color iHighlight) {
x = ix;
y = iy;
size = isize;
edgeCol = edColor;
baseColor = iColor;
hoverColor = iHover;
highlightColor = iHighlight;
currentColor = baseColor;
}
boolean over() {
if (mouseX >= x && mouseX <= x+size &&
mouseY >= y && mouseY <= y+size) {
return true;
} else {
return false;
}
}
void display() {
stroke(edgeCol);
fill(currentColor);
rect(x, y, size, size);
}
}
Also, here's a little test program to test them:
- /** Scrollbar 0.12
Scrollbars and buttons test.
Also testing button and slider arrays, with different "loosiness" of sliders.
Public Domain :p
2012.05.08 - raron - Improved classes a bit.
*/
// Nr. of test controls of each type
int bars = 8;
// Scrollbars and buttons
VScrollbar Vslider [];
HScrollbar Hslider [];
CircleButton oButton [];
RectButton xButton [];
void setup()
{
size (400,500);
// Scrollbar/slider colors
color scrEdgdeCol = color(0,0,0);
color scrBgCol = color(100,100,100);
color sliderColor = color(0,150,200);
color scrHoverCol = color(100,200,200);
color scrPressCol = color(100,255,255);
// Button colors
color btnEdgeCol = color(255,255,0);
color btnColor = color(0,0,0);
color btnHoverCol = color(0,200,0);
color btnPressCol = color(200,0,0);
// The scrollbars (or sliders) and buttons array initialization
Vslider = new VScrollbar[bars];
Hslider = new HScrollbar[bars];
oButton = new CircleButton[bars];
xButton = new RectButton[bars];
// The scrollbars (or sliders) and buttons array instantiation
for (int i=0; i<bars; i++) {
Vslider[i] = new VScrollbar(10+i*20, 20, 16, 200, i*2, scrEdgdeCol, scrBgCol, sliderColor, scrHoverCol, scrPressCol);
Hslider[i] = new HScrollbar(10, 250+i*30, 250, 8+i*3, i*2, scrEdgdeCol, scrBgCol, sliderColor, scrHoverCol, scrPressCol);
oButton[i] = new CircleButton(bars*20+30, 20+i*30, (i+4)*3, btnEdgeCol, btnColor, btnHoverCol, btnPressCol);
xButton[i] = new RectButton(bars*20+70-(bars+4-i), 20+i*30, (bars+4-i)*2, btnEdgeCol, btnColor, btnHoverCol, btnPressCol);
}
// Set some initial slider values for fun
for (int i=0; i<bars; i++) {
Vslider[i].setValue(1-0.66*cos((float)(i+1)/(bars*4)*2*PI));
Hslider[i].setValue(0.78*sin((float)(bars-i)/(bars*3)*2*PI));
}
}
void draw()
{
background(192,192,192);
fill(0,0,0);
text("Sliders and buttons test 0.12",10,10);
for (int i=0; i<bars; i++) {
if (oButton[i].clicked() == true) println("Round button " + i + " clicked!");
if (oButton[i].pressed() == true) print("-");
if (xButton[i].clicked() == true) println("Square Button " + i + " clicked!");
if (xButton[i].pressed() == true) print("-");
// Write only the horizontal slider values
text("Hs " + i + ": " + Hslider[i].value(), 265, 265+i*30);
// Scrollbars/sliders and buttons updates and displaying
Vslider[i].update();
Vslider[i].display();
Hslider[i].update();
Hslider[i].display();
oButton[i].update();
oButton[i].display();
xButton[i].update();
xButton[i].display();
}
}