How would I condense this code into classes, objects etc?

I stumbled across this online, and I want to use it for reference, but it seems really jumbled. Any idea how I can organize this better into objects, classes, etc?

color background_color = color(58, 250, 94);
color entry_color = color(183, 255, 245);
color entry_text_color = color(10, 3, 40);
color button_color = color(233, 255, 143);
color button_text_color = color(93, 67, 247);

char pKey=' ';
float value_1, value_2, position=0;
String operation;

String entery_text="Calculator";

void setup(){
  size(400, 500);
  background(background_color);
  noStroke();
  textSize(60);
}

void draw(){
  reset();
  input();
  
}

void reset(){
  background(background_color);
  
  fill(entry_color);
  rect(10, 10, 380, 70);
  
  fill(entry_text_color);
  text(entery_text, 20, 67);
  
  fill(button_color);
  
  rect(10, 100, 80, 80, 20);
  rect(110, 100, 80, 80, 20);
  rect(210, 100, 80, 80, 20);
  rect(310, 100, 80, 80, 20);
  
  rect(10, 200, 80, 80, 20);
  rect(110, 200, 80, 80, 20);
  rect(210, 200, 80, 80, 20);
  rect(310, 200, 80, 80, 20);
  
  rect(10, 300, 80, 80, 20);
  rect(110, 300, 80, 80, 20);
  rect(210, 300, 80, 80, 20);
  rect(310, 300, 80, 80, 20);
  
  rect(10, 400, 80, 80, 20);
  rect(110, 400, 80, 80, 20);
  rect(210, 400, 80, 80, 20);
  rect(310, 400, 80, 80, 20);
  
  fill(button_text_color);
  
  text("7", 27, 162);
  text("8", 127, 162);
  text("9", 227, 162);
  text("/", 333, 155);
  
  text("4", 27, 262);
  text("5", 127, 262);
  text("6", 227, 262);
  text("x", 327, 262);
  
  text("1", 27, 362);
  text("2", 127, 362);
  text("3", 227, 362);
  text("-", 327, 362);
  
  text("C", 27, 462);
  text("0", 127, 462);
  text("=", 227, 462);
  text("+", 327, 462);
}

void input(){
  if(keyPressed/* && (key!=pKey)*/){
    delay(150);
    //pKey = key;
    if(key=='0'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+0;
      }
      else if(position==2){
        value_2 = (value_2*10)+0;
      }
      else if(position==4){
        value_1=0;
        position=0;
      }
    }
    else if(key=='1'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+1;
      }
      else if(position==2){
        value_2 = (value_2*10)+1;
      }
      else if(position==4){
        value_1=1;
        position=0;
      }
    }
    else if(key=='2'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+2;
      }
      else if(position==2){
        value_2 = (value_2*10)+2;
      }
      else if(position==4){
        value_1=2;
        position=0;
      }
    }
    else if(key=='3'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+3;
      }
      else if(position==2){
        value_2 = (value_2*10)+3;
      }
      else if(position==4){
        value_1=3;
        position=0;
      }
    }
    else if(key=='4'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+4;
      }
      else if(position==2){
        value_2 = (value_2*10)+4;
      }
      else if(position==4){
        value_1=4;
        position=0;
      }
    }
    else if(key=='5'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+5;
      }
      else if(position==2){
        value_2 = (value_2*10)+5;
      }
      else if(position==4){
        value_1=5;
        position=0;
      }
    }
    else if(key=='6'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+6;
      }
      else if(position==2){
        value_2 = (value_2*10)+6;
      }
      else if(position==4){
        value_1=6;
        position=0;
      }
    }
    else if(key=='7'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+7;
      }
      else if(position==2){
        value_2 = (value_2*10)+7;
      }
      else if(position==4){
        value_1=7;
        position=0;
      }
    }
    else if(key=='8'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+8;
      }
      else if(position==2){
        value_2 = (value_2*10)+8;
      }
      else if(position==4){
        value_1=8;
        position=0;
      }
    }
    else if(key=='9'){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+9;
      }
      else if(position==2){
        value_2 = (value_2*10)+9;
      }
      else if(position==4){
        value_1=9;
        position=0;
      }
    }
    
    else if(key=='+'){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="+";
      }
    }
    else if(key=='-'){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="-";
      }
    }
    else if(key=='*'){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="*";
      }
    }
    else if(key=='/'){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="/";
      }
    }
    else if(key=='='){
      if(operation=="+"){
        value_1 += value_2;
      }
      else if(operation=="-"){
        value_1 -= value_2;
      }
      else if(operation=="*"){
        value_1 *= value_2;
      }
      else if(operation=="/"){
        value_1 /= value_2;
      }
      position=4;
      value_2=0;
      operation="";
    }
    else if(key=='C' || key=='c'){
      exit();
    }
  }
  
  else if(mousePressed){
    delay(150);
    if(mouseX>110&&mouseX<190&&mouseY>400&&mouseY<480){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+0;
      }
      else if(position==2){
        value_2 = (value_2*10)+0;
      }
      else if(position==4){
        value_1=0;
        position=0;
      }
    }
    else if(mouseX>10&&mouseX<90&&mouseY>300&&mouseY<380){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+1;
      }
      else if(position==2){
        value_2 = (value_2*10)+1;
      }
      else if(position==4){
        value_1=1;
        position=0;
      }
    }
    else if(mouseX>110&&mouseX<190&&mouseY>300&&mouseY<380){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+2;
      }
      else if(position==2){
        value_2 = (value_2*10)+2;
      }
      else if(position==4){
        value_1=2;
        position=0;
      }
    }
    else if(mouseX>210&&mouseX<290&&mouseY>300&&mouseY<380){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+3;
      }
      else if(position==2){
        value_2 = (value_2*10)+3;
      }
      else if(position==4){
        value_1=3;
        position=0;
      }
    }
    else if(mouseX>10&&mouseX<90&&mouseY>200&&mouseY<280){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+4;
      }
      else if(position==2){
        value_2 = (value_2*10)+4;
      }
      else if(position==4){
        value_1=4;
        position=0;
      }
    }
    else if(mouseX>110&&mouseX<190&&mouseY>200&&mouseY<280){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+5;
      }
      else if(position==2){
        value_2 = (value_2*10)+5;
      }
      else if(position==4){
        value_1=5;
        position=0;
      }
    }
    else if(mouseX>210&&mouseX<290&&mouseY>200&&mouseY<280){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+6;
      }
      else if(position==2){
        value_2 = (value_2*10)+6;
      }
      else if(position==4){
        value_1=6;
        position=0;
      }
    }
    else if(mouseX>10&&mouseX<90&&mouseY>100&&mouseY<180){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+7;
      }
      else if(position==2){
        value_2 = (value_2*10)+7;
      }
      else if(position==4){
        value_1=7;
        position=0;
      }
    }
    else if(mouseX>110&&mouseX<190&&mouseY>100&&mouseY<180){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+8;
      }
      else if(position==2){
        value_2 = (value_2*10)+8;
      }
      else if(position==4){
        value_1=8;
        position=0;
      }
    }
    else if(mouseX>210&&mouseX<290&&mouseY>100&&mouseY<180){
      if(position==1){
        position=2;
      }
      if(position==0){
        value_1 = (value_1*10)+9;
      }
      else if(position==2){
        value_2 = (value_2*10)+9;
      }
      else if(position==4){
        value_1=9;
        position=0;
      }
    }
    
    else if(mouseX>310&&mouseX<390&&mouseY>400&&mouseY<480){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="+";
      }
    }
    else if(mouseX>310&&mouseX<390&&mouseY>300&&mouseY<380){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="-";
      }
    }
    else if(mouseX>310&&mouseX<390&&mouseY>200&&mouseY<280){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="*";
      }
    }
    else if(mouseX>310&&mouseX<390&&mouseY>100&&mouseY<180){
      if(position==0){
        position=1;
      }
      else if(position==4){
        position=1;
      }
      if(position==1){
        operation="/";
      }
    }
    else if(mouseX>210&&mouseX<290&&mouseY>400&&mouseY<480){
      if(operation=="+"){
        value_1 += value_2;
      }
      else if(operation=="-"){
        value_1 -= value_2;
      }
      else if(operation=="*"){
        value_1 *= value_2;
      }
      else if(operation=="/"){
        value_1 /= value_2;
      }
      position=4;
      value_2=0;
      operation="";
    }
    else if(mouseX>10&&mouseX<90&&mouseY>400&&mouseY<480){
      exit();
    }
  }
  
  
  
  
  
  if(position==0||position==4){
    entery_text = str(value_1);
  }
  
  else if(position==1){
    entery_text = str(value_1)+operation;
  }
  
  else if(position==2){
    entery_text = str(value_1)+operation+str(value_2);
  }

}

Hello @WeeBoEtte! It’s quite a lot of information to put into a post. However, there’s a better way! These two playlists – Functions (4 videos) and OOP (6 videos) – by Dan Shiffman are an excellent place to start for nice introduction. Broken down into very manageable parts.
I would recommend watching these first, take notes, try to implement with the non-OOP calculator code you have, then return with questions as they arise.
:nerd_face:

1 Like

Hello,

I am glad you’re making progress with your calculator

You asked about classes, objects. The core idea is that you can pack the properties of one button (x-position, y-position, size, text…) into one package, the class. Then you can have a list of the buttons and check the buttons in a for-loop over this list (array). So you can shorten your code for displaying the buttons.

In the long run this is very comfortable and gives you good code, because when you check the buttons in a for loop, one change you make in the code is for all the buttons, so you can improve your code fast.

Explanation
In your code, where you display the buttons you have numbers (button positions etc.) and where you check whether the mouse is in the button you also have (the same) numbers. This makes the code very long. At if you were to make the distances between the buttons bigger it would be a real hassle. When you store the buttons in the class, you only have the numbers once and store them and can then use them everywhere:

  • I define the buttons as objects (of the class) in a list in setup()
  • In draw() I display the buttons (using a for loop)
  • In mousePressed() I check on which button the mouse was pressed.

Also, you can work with for loops instead of displaying every button separately. The concept of classes and objects supports this.
There is a nice tutorial about objects. https://www.processing.org/tutorials/objects/

  • The class is the cookie maker, the objects in the list are the cookies. The class represents only ONE button but like the cookie maker, the cookies are made from this class (having individual position etc.).

Below is an example. (It’s showing the principle of buttons as objects in a list (array), it’s not a working calculator).

(In your other thread you have a class keypad instead of having a class Button:

  • I think the keypad is one abstraction level too high. And you can’t have a list of keypads. And inside the keypad class you have still the numbers for displaying and checking the mouse. Bad.
  • You could have a class Button and then a class keyPad on top of it (inside class keyPad would be the list of buttons of class Button). But in my opinion the button class with a list of buttons would be the way to go first.)

Please come back when you have more questions.

Warm regards, Chrisir

// Naming conventions; I use this throughout :  
//   class = UpperCase and singular (contains only ONE circle) - CircleButton
//   array = lowerCase and plural (contains many circles)      - myCircleButtons 
//   object / variable = lowerCase and singular                - button / myCircleSize 

CircleButton[] myCircleButtons = new CircleButton[6]; // 

//int state; 

String buttonSaid = ""; 

final int typeNumber =0; 
final int typeCommand=1; 

void setup() {
  size(1290, 790);
  background(120);  // new

  // DEFINE ALL BUTTONS
  int myCircleSize = 100; //

  // random color - color when mouse is NOT over this button
  color myColor = color(0, random(255), random(255));  
  // position 
  int x1=110; 
  int y1=110; 
  for (int i = 0; i < myCircleButtons.length; i++) {
    // define button and put it into the array 
    myCircleButtons[i] = new CircleButton(
      x1, // x-value 
      y1, // y-value
      myCircleSize, // size 
      myColor, // color
      str(i), // its text  
      typeNumber );
    x1+= (myCircleSize+14);  // increase x-position 
    if (i==1||i==3) { // new line 
      x1=110; 
      y1+=myCircleSize+22;
    }
  }//for

  // change buttons individually: 
  myCircleButtons[5].text = "+";
  myCircleButtons[5].type = typeCommand;   // type: not a number but a command 
  myCircleButtons[5].baseColor = color(0, 0, 255);
 
}//function 

void draw() {
  background(120); // the image is more crisp with background 
  fill(255);

  // the calculator's display 
  text(buttonSaid, 
    200, 24);

  // display all buttons
  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    button.update();
  }//for
}//function 

// -------------------------------------------------------------------------
// Input functions 

void mousePressed() {
  // check mouse on all buttons 
  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    if (button.overCircle()) {
      buttonSaid=button.text;
      return;
    }//if
  }//for
}

// ======================================================================== // line to show: here starts a class

class CircleButton {

  int circleX, circleY;  // Position of circle button
  int circleSize;     // Diameter of circle

  color circleColor = color(255, 0, 0);  // RED when over!!!!!!!!!!!!!!!
  color baseColor;  // when not over - gets defined in the constructor

  boolean circleOver = false; // not really in use, never mind 

  int type;

  String text; 

  // constructor
  CircleButton(int posX_, int posY_, // linebreaks for better readability. Marking parameters with a _ sign. 
    int theSize_, 
    color baseColor_, 
    String text_, 
    int type_) { 
    // constructor 
    circleX = posX_;
    circleY = posY_;
    circleSize = theSize_;
    baseColor = baseColor_;
    type=type_;
    text=text_;

    ellipseMode(CENTER);
  }// constructor

  void update() {    
    // make use of circleColor and  baseColor
    if (overCircle()) {
      fill( circleColor ); // over 
      stroke(255);
    } else {
      fill( baseColor ); // not over
      noStroke();
    }
    ellipse(circleX, circleY, 
      circleSize, circleSize);
    fill(255);
    textAlign(CENTER);
    textSize(22);
    text(text, 
      circleX, circleY);
    //reset
    textAlign(LEFT);
  }//method

  boolean overCircle() { 
    if (dist(mouseX, mouseY, circleX, circleY) < circleSize/2 ) { // using in-build function dist() here!
      circleOver = true;
      return true;
    } else {
      circleOver = false;
      return false;
    }
  }//method

  void printlnProperties() {
    //
    println (text +"\t"+ "" +"\t"+ type);
  }//method
  //
}//class // marking the end of the class 
//