Loading...
Logo
Processing Forum
I'm making a calculator as a beginning project. Everything has been going fine until I got to programming the buttons. When I tried to implement button hover detection instead of detecting over the button it detected over the screen (number output). 
My code is below:
Calculator.pde
Copy code
  1. import java.text.NumberFormat;
  2. import java.text.DecimalFormat;
  3. PFont f;
  4. final int topRowYPos = 80;
  5. final int secondRowYPos = 110;
  6. final int thirdRowYPos = 140;
  7. final int fourthRowYPos = 170;
  8. final int fithRowYPos = 200;
  9. final int sixthRowYPos = 230;
  10. final int buttonWidth = 35;
  11. final int buttonHeight = 25;
  12. final int firstRowXPos = 45;
  13. final int secondRowXPos = 85;
  14. final int thirdRowXPos = 125;
  15. final int fourthRowXPos = 165;
  16. final int fithRowXPos = 205;
  17. int digitCount;
  18. boolean isDecimal;
  19. double numOneBuffer;
  20. double numTwoBuffer;
  21. double screenBuffer;
  22. double numMemorY;
  23. Button mc = new Button(firstRowXPos, secondRowYPos);
  24. Button percent = new Button(firstRowXPos, thirdRowYPos);
  25. NumberFormat formatter = new DecimalFormat("0.0000000");
  26. void setup() {
  27.   size(250, 280);
  28. }
  29. void draw() {
  30.   if (mc.overButton()) {
  31.     println("Over MC");
  32.   }
  33.   screenBuffer = 00.111;
  34.   rectMode(CENTER);
  35.   fill(255);
  36.   rect(125, 140, 240, 270);
  37.   rect(125, 40, 220, 30);
  38.   rect(firstRowXPos, secondRowYPos, buttonWidth, buttonHeight, 7);
  39.   rect(firstRowXPos, thirdRowYPos, buttonWidth, buttonHeight, 7);
  40.   rect(firstRowXPos, fourthRowYPos, buttonWidth, buttonHeight, 7);
  41.   rect(firstRowXPos, fithRowYPos, buttonWidth, buttonHeight, 7);
  42.   rect(firstRowXPos, sixthRowYPos, buttonWidth, buttonHeight, 7);
  43.   rect(secondRowXPos, secondRowYPos, buttonWidth, buttonHeight, 7);
  44.   rect(secondRowXPos, thirdRowYPos, buttonWidth, buttonHeight, 7);
  45.   rect(secondRowXPos, fourthRowYPos, buttonWidth, buttonHeight, 7);
  46.   rect(secondRowXPos, fithRowYPos, buttonWidth, buttonHeight, 7);
  47.   rect(secondRowXPos, sixthRowYPos, buttonWidth, buttonHeight, 7);
  48.   rect(thirdRowXPos, secondRowYPos, buttonWidth, buttonHeight, 7);
  49.   rect(thirdRowXPos, thirdRowYPos, buttonWidth, buttonHeight, 7);
  50.   rect(thirdRowXPos, fourthRowYPos, buttonWidth, buttonHeight, 7);
  51.   rect(thirdRowXPos, fithRowYPos, buttonWidth, buttonHeight, 7);
  52.   rect(thirdRowXPos, sixthRowYPos, buttonWidth, buttonHeight, 7);
  53.   rect(fourthRowXPos, topRowYPos, buttonWidth, buttonHeight, 7);
  54.   rect(fourthRowXPos, secondRowYPos, buttonWidth, buttonHeight, 7);
  55.   rect(fourthRowXPos, thirdRowYPos, buttonWidth, buttonHeight, 7);
  56.   rect(fourthRowXPos, fourthRowYPos, buttonWidth, buttonHeight, 7);
  57.   rect(fourthRowXPos, fithRowYPos, buttonWidth, buttonHeight, 7);
  58.   rect(fourthRowXPos, sixthRowYPos, buttonWidth, buttonHeight, 7);
  59.   rect(fithRowXPos, topRowYPos, buttonWidth, buttonHeight, 7);
  60.   rect(fithRowXPos, secondRowYPos, buttonWidth, buttonHeight, 7);
  61.   rect(fithRowXPos, thirdRowYPos, buttonWidth, buttonHeight, 7);
  62.   rect(fithRowXPos, fourthRowYPos, buttonWidth, buttonHeight, 7);
  63.   rect(fithRowXPos, 215, buttonWidth, 55, 7);
  64.   f = createFont("Georgia", 16);
  65.   textFont(f);
  66.   textAlign(CENTER, CENTER);
  67.   fill(0);
  68.   text("MC", firstRowXPos, secondRowYPos);
  69.   text("%", firstRowXPos, thirdRowYPos);
  70.   text("+/-", firstRowXPos, fourthRowYPos);
  71.   text("C", firstRowXPos, fithRowYPos);
  72.   text("AC", firstRowXPos, sixthRowYPos);
  73.   text("MR", secondRowXPos, secondRowYPos);
  74.   text("7", secondRowXPos, thirdRowYPos);
  75.   text("4", secondRowXPos, fourthRowYPos);
  76.   text("1", secondRowXPos, fithRowYPos);
  77.   text("0", secondRowXPos, sixthRowYPos);
  78.   text("M-", thirdRowXPos, secondRowYPos);
  79.   text("8", thirdRowXPos, thirdRowYPos);
  80.   text("5", thirdRowXPos, fourthRowYPos);
  81.   text("2", thirdRowXPos, fithRowYPos);
  82.   text("=", thirdRowXPos, sixthRowYPos);
  83.   text("√", fourthRowXPos, topRowYPos);
  84.   text("M+", fourthRowXPos, secondRowYPos);
  85.   text("9", fourthRowXPos, thirdRowYPos);
  86.   text("6", fourthRowXPos, fourthRowYPos);
  87.   text("3", fourthRowXPos, fithRowYPos);
  88.   text(".", fourthRowXPos, sixthRowYPos);
  89.   text("off", fithRowXPos, topRowYPos);
  90.   text("÷", fithRowXPos, secondRowYPos);
  91.   text("*", fithRowXPos, thirdRowYPos);
  92.   text("-", fithRowXPos, fourthRowYPos);
  93.   text("+", fithRowXPos, 215);
  94.   text(formatter.format(screenBuffer), 125, 40);
  95. }
  96. void mousePressed() {
  97.   String debugString = mouseX +","+ mouseY;
  98.   println(debugString);
  99. }

Button.pde:
Copy code
  1. class Button {
  2.   final int buttonWidth = 35;
  3.   final int buttonHeight = 25;
  4.   int xPos, yPos;
  5.   Button (int y, int x) {
  6.     xPos = x;
  7.     yPos = y;
  8.   }
  9.   boolean overButton() {
  10.     if (mouseX >= xPos && mouseX <= xPos+buttonWidth && 
  11.       mouseY >= yPos && mouseY <= yPos+buttonHeight) {
  12.       return true;
  13.     }
  14.     else {
  15.       return false;
  16.     }
  17.   }
  18. }
Thanks in advance.

Replies(4)

I've spotted the bug -> You use a diff. rectMode()! Rather than default's CORNER, you've chosen CENTER.
The catch is, a rect() is now drawn from its center coordinates rather than its left-top 1s.
So, your isOverButton() method fails miserably! 

Below lies your Button class fixed:
Copy code
    class Button {
      static final int BTN_DX = 35, BTN_DY = 25; // diameters x, y
      static final int BTN_RX = BTN_DX >> 1;     // radius x
      static final int BTN_RY = BTN_DY >> 1;     // radius y
    
      final int left, right, top, bottom; // button edges
    
      Button (int cx, int cy) {  // centralized positions x, y
        left = cx - BTN_RX;
        right = cx + BTN_RX;
        top = cy - BTN_RY;
        bottom = cy + BTN_RY;
      }
    
      boolean isOverButton() {
        return mouseX > left & mouseX < right 
          & mouseY > top & mouseY < bottom;
      }
    }
    

err....
If I am not mistaken,
  • you swapped x and y in line 6 of Button.pde
  • also try to save your sketch as calc.pde because processing doesn't like it when sketch has the same name as a class in it (Button)
also, I noticed you use
Copy code
  1.   rectMode(CENTER);
Therefore x,y is the center whereas in line 11/12 you assume it is the upper left corner.
Therefore you need to hover little below and right from the text "MC" to get a result.
So either delete rectMode(CENTER); or change line 11/12


Arrays and class
your code is very long winded
I understand you are turning it into a class. Good.
The goal is:
  • have rect painted in the class
  • have text in the class
You don't have that yet.

But if you do:
You would end up with code like
Copy code
  1. mc.display();
  2. percent.display();
  3. ....
etc. for all (!) buttons.
 
To avoid long code like this I recommend using an array of that class.

Thus you could for loop over the class
Copy code
  1. for i......... {
  2. buttons[i].display();
  3. }


Defining the array

So instead of
Copy code
  1. Button mc = new Button(firstRowXPos, secondRowYPos);

you'd say

Copy code
  1. int max = 36; // max buttons
  2. Button[] buttons = new Button [max];  // array
  3. buttons[0] = new Button (firstRowXPos, secondRowYPos, "MC");  // 1st object in the class
(That part would still be long since you need to define the buttons, but then the rest will be short)

Greetings, Chrisir

If you need an answer, please send me a personal message since this forum doesn't notify.


GoToLoop, I was working on it and hadn't seen yours
well spotted

Greetings, Chrisir