1

How can I create a slider with two arrow buttons from the side? The arrows/triangle should turn white when clicked. And the slider should move each time the arrow button is clicked.

a left arrow square gray button, a slider with a white handle and gray background and a right arrow square gray button on a black background

here's the link to what it should look like

and here's what I've done so far

int x=75;

void setup() {
  size(600,400);
}

void draw() {
  background(100);
  fill (200);
  rect (75, 25, 400, 50);
  stroke(0);
  
  if(mousePressed) {
  if (mouseX >75 && mouseX <= 475)
    {x=mouseX;}
    }

  fill(127,0,0);
  rect (x, 20, 9, 60); 
  fill (255);

fill (200);
  rect (10, 25, 50, 50);
{
  if (mousePressed == true) {
    fill(255);
  } else {
    fill(0);
  }
  
  triangle (50, 60, 50, 40, 15, 50);
}
  
  fill (200);
  rect (490, 25, 50, 50);
  
  {
  if (mousePressed == true) {
    fill(255);
  } else {
    fill(0);
  }
  
  triangle (500, 60, 500, 40, 535, 50);
}
  
  
  println(x);
  
}

When I click anywhere on the screen, my problem is that both arrows turn white. I need it to individually function. And the slider is not moving every time I click the arrow buttons

Zoe
  • 27,060
  • 21
  • 118
  • 148
  • Why are you changing your question? – matt May 29 '22 at 11:31
  • Please do not vandalize your posts. Once you have submitted a post, you have licensed the content to the Stack Overflow community at large ([under the CC BY-SA license](//creativecommons.org/licenses/by-sa/4.0/)). By Stack Exchange policy, all vandalism will be reverted. – Stephen Ostermiller May 29 '22 at 11:34
  • I remember checking the users around the time of the original post and it seemed to me there were a bunch of students from the Philippines scrambling to get their assignments done. They probably wanted to cover their tracks. Here are a couple of related posts (from similar dates): https://stackoverflow.com/questions/72313759/making-a-discrete-slider-using-processing , https://stackoverflow.com/questions/72334829/snapping-value-bar. – George Profenza Jun 07 '22 at 22:50

2 Answers2

1

The following approach to this problem uses 4 different classes: ForwardArrow, BackArrow, Slider, and ValueField. Arrow fill color is controlled by the press() method of its respective class.

color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);
color GREEN = color(32, 175, 47);

ForwardArrow _fwdArrw;
BackArrow _backArrw;
ValueField _valueFld;
Slider _slider;

final int _sliderX = 90;
final int _sliderY = 40;
final int _sliderW = 200;
final int _sliderH = 30;

final int _txtSize = 22;

final int _initValue = 40;
final int _maxValue = 200;
final int _minValue = 0;

int value = _initValue;

class ValueField {
  float x, y, w, h;
  String title;
  color fldColor;
  color txtColor;

  // Constructor
  ValueField(int xpos, int ypos, float wt, float ht, String valueStr, color background, color foreground) {
    x = xpos;
    y = ypos;
    w = wt;
    h = ht;
    title = valueStr;
    fldColor = background;
    txtColor = foreground;
  }

  void display(int val) {
    // **** Value Field **** //
    fill(fldColor); // erase old value
    rect(x, y, w, h);
    fill(txtColor); // text color
    textSize(_txtSize);
    textAlign(CENTER);
    text(str(val), x, y, w, h);
    // **** Slider bar **** //
    fill(255);
    rect(_sliderX, _sliderY, _sliderW*val/_maxValue, _sliderH);
  }
}

class ForwardArrow {
  float x, y, w, h;
  color arrwColor;
  // Constructor
  ForwardArrow(int xpos, int ypos, float wt, float ht, color background) {
    x = xpos;
    y = ypos;
    w = wt;
    h = ht;
    arrwColor = background;
  }

  void display() {
    fill(arrwColor); // arrow color
    noStroke();
    triangle(x, y, x, y + h, x + w, y + h/2 );
  }

  void press() {
    fill(255); // arrow color
    noStroke();
    triangle(x, y, x, y + h, x + w, y + h/2 );
  }
}

class BackArrow {
  float x, y, w, h;
  color arrwColor;

  // Constructor
  BackArrow(int xpos, int ypos, float wt, float ht, color background) {
    x = xpos;
    y = ypos;
    w = wt;
    h = ht;
    arrwColor = background;
  }

  void display() {
    fill(arrwColor);
    noStroke();
    triangle(x, y + h/2, x + w, y, x + w, y + h );
  }

  void press() {
    fill(255);
    noStroke();
    triangle(x, y + h/2, x + w, y, x + w, y + h );
  }
}

class Slider {
  float x, y, w, h;
  color barColor;
  color trimColor;

  // Constructor
  Slider(int xpos, int ypos, float wt, float ht, color background, color foreground) {
    x = xpos;
    y = ypos;
    w = wt;
    h = ht;
    barColor = background;
    trimColor = foreground;
  }

  void display() {
    stroke(0);
    strokeWeight(1);
    noFill();
    rect(x, y, w, h);
  }
}

void setup() {
  size(500, 250);
  background(BLUE);
  _slider = new Slider(_sliderX, _sliderY, _sliderW, _sliderH, WHITE, BLACK);
  _backArrw = new BackArrow(50, 40, 30, 30, GREEN);
  _fwdArrw = new ForwardArrow(300, 40, 30, 30, GREEN);
  _valueFld = new ValueField(380, 40, 60, 30, str(_initValue), WHITE, BLACK);
}

void draw() {
  background(BLUE);
  _valueFld.display(value);
  _fwdArrw.display();
  _backArrw.display();
  _slider.display();

  // FwdArrw Long Press
  if ((mouseX >= _fwdArrw.x) && (mouseX <= _fwdArrw.x + _fwdArrw.w) && (mouseY >= _fwdArrw.y) && (mouseY <= _fwdArrw.y + _fwdArrw.h)) {
    if (mousePressed == true) {
      _fwdArrw.press();
      value++;
      if (value > _maxValue) {
        value = _maxValue;
      }
      _valueFld.display(value);
    }
  }
  // BackArrw Long Press
  if ((mouseX >= _backArrw.x) && (mouseX <= _backArrw.x + _backArrw.w) && (mouseY >= _backArrw.y) && (mouseY <= _backArrw.y + _backArrw.h)) {
    if (mousePressed == true) {
      _backArrw.press();
      value--;
      if (value < _minValue) {
        value = _minValue;
      }
      _valueFld.display(value);
    }
  }
}

A revision of your code follows;

int x=75;

void setup() {
  size(600, 400);
}

void draw() {
  background(100);
  fill (200);
  rect (75, 25, 400, 50); // slider bar
  stroke(0);

  fill(127, 0, 0);
  rect (x, 20, 9, 60); // slider thumb

  fill (200);
  rect (10, 25, 50, 50);  // back arrow
  fill(0);
  triangle (50, 60, 50, 40, 15, 50);
  if ((mouseX >= 10) && (mouseX <= 10 + 50) && (mouseY >= 25) && (mouseY <= 25 + 50) ) {
    if (mousePressed == true) {
      fill(255);
      triangle (50, 60, 50, 40, 15, 50);
      x--;
      if (x<75) {
        x = 75;  // minValue
      }
    } else {
      fill(0);
      triangle (50, 60, 50, 40, 15, 50);
    }
  }

  fill (200);
  rect (490, 25, 50, 50); //forward arrow
  fill(0);
  triangle (500, 60, 500, 40, 535, 50);
  if ((mouseX >= 490) && (mouseX <= 490 + 50) && (mouseY >= 25) && (mouseY <= 25 + 50) ) {
    if (mousePressed == true) {
      fill(255);
      triangle (500, 60, 500, 40, 535, 50);
      x++;
      if (x>466) {
        x = 466; // maxValue
      }
    } else {
      fill(0);
      triangle (500, 60, 500, 40, 535, 50);
    }
  }
}

apodidae
  • 1,988
  • 2
  • 5
  • 9
0

You've got part of the logic right for the slider/trackbar so it changes x only within a range. This happens horizontally only at this stage, but you can use the same logic to check horizontal limits as well. Similarly, you can check if the cursor is within the bounds of any rectangle (be it the slider or either of the buttons):


int x=75;

void setup() {
  size(600, 400);
}

void draw() {
  background(100);
  
  // slider
  fill (200);
  rect (75, 25, 400, 50);
  stroke(0);
  if (mousePressed) {
    if (mouseX >75 && mouseX <= 475)
    {
      x=mouseX;
    }
  }

  fill(127, 0, 0);
  rect (x, 20, 9, 60); 
  fill (255);

  // left arrow button
  fill (200);
  rect (10, 25, 50, 50);
  fill(0);
  if (mousePressed == true) {
    if (mouseX > 10 && mouseX <= 10 + 50 && mouseY > 25 && mouseY <= 25 + 50){
      fill(255);  
    }
  }
  triangle (50, 60, 50, 40, 15, 50);

  // right arrow button
  fill (200);
  rect (490, 25, 50, 50);
  fill(0);
  if (mousePressed == true) {
    if (mouseX > 490 && mouseX <= 490 + 50 && mouseY > 25 && mouseY <= 25 + 50){
      fill(255);  
    }
  }
  triangle (500, 60, 500, 40, 535, 50);


  println(x);
}

Wouldn't it be nice if you could take that logic and instead of copy/pasting the different x,y,width,height parameters for the same 4 statements you could group that functionality in a reusable block of code ?

That what functions are for. You're already using them already (defining setup()/draw(), calling background()/fill()/etc.

The Processing Button example already provides the boolean overRect(int x, int y, int width, int height) function which is perfect for you're trying to achieve: pass in the x,y,width,height or a button and get back boolean value.

Here's your code using the overRect():

int x=75;

void setup() {
  size(600, 400);
}

void draw() {
  background(100);
  
  // slider
  fill (200);
  rect (75, 25, 400, 50);
  stroke(0);
  if (mousePressed) {
    if (mouseX >75 && mouseX <= 475)
    {
      x=mouseX;
    }
  }

  fill(127, 0, 0);
  rect (x, 20, 9, 60); 
  fill (255);

  // left arrow button
  fill (200);
  rect (10, 25, 50, 50);
  fill(0);
  if (mousePressed && overRect(10, 25, 50, 50)) {
    fill(255);  
    x--;
  }
  triangle (50, 60, 50, 40, 15, 50);

  // right arrow button
  fill (200);
  rect (490, 25, 50, 50);
  fill(0);
  if (mousePressed && overRect(490, 25, 50, 50)){
      fill(255);
      x++;
  }
  triangle (500, 60, 500, 40, 535, 50);

  // ensure x remains within the slide limits
  x = constrain(x, 75, 475);
  println(x);
}

boolean overRect(int x, int y, int width, int height)  {
  if (mouseX >= x && mouseX <= x+width && 
      mouseY >= y && mouseY <= y+height) {
    return true;
  } else {
    return false;
  }
}
George Profenza
  • 50,687
  • 19
  • 144
  • 218