Loading...
Logo
Processing Forum

Mouse click on object

in Programming Questions  •  1 years ago  
I would like to know if it is possible to associate a mouse click event with an object (because it was clicked over it).
I do not mean use the window coords and calculate whether it was over the object, so, I would presume that the coding for the mouse would have to be part of the object's class code.
The end result would therefore be that the mouse coords returned would naturally be relative to the object, without any calculations.
 
Perhaps?? I could have made that simpler by asking whether object's can have mouse events as well as properties and methods.
Thanks in advance

Replies(7)

the answer is: no. 


what you're describing is very common in many graphics libraries, e.g. javascript/html, adobe flash. 
for reference: such thing is called a scenegraph and processing does not support it (directly). 
(i think this is not for technical reasons, more because it interferes with the simple drawing concept processing tries to have at it's core). 


however, there a few examples in the learning section, 

look at everything in the gui section, mostly the button and buttons examples. 



just to be clear: if all you want is a scenegraph, processing is usually the wrong choice. 
Thank you for your response. I have never heard of scenegraph. This makes me wonder whether I explained correctly. I have looked at button as suggested and it appears not to be using the shapes as objects and so only suggests that it can be done the way I do not want to do it... by calculating.
 
If I have 50 objects as instances of a class on screen and click on one that is at 300,400 but 3 pixels inside it (both x & y) I would want the object to be able to react and change its own colour (say) and know that the mouse is at point 3,3 (not 303,403) without the [external, to the class] code having to do it.
This is normal in for example Delphi and other oop languages and it can be done as an object event or an operating system event. I hope I explained it wrongly!!
hey! 


Thank you for your response. I have never heard of scenegraph. 

it's a very generic term, with a slightly fuzzy description, 
but it's pretty exactly what you want it seems. 

This makes me wonder whether I explained correctly. I have looked at button as suggested and it appears not to be using the shapes as objects and so only suggests that it  can be done the way I do  not want to do it... by calculating.
somewhere those calculations have to happen, if you do not see those calculations it means they're done by a library and are simply hidden from you.  
 

If I have 50 objects as instances of a class on screen and click on one that is at 300,400 but 3 pixels inside it (both x & y) I would want the object to be able to react and change its own colour (say) and know that the mouse is at point 3,3 (not 303,403) without the [external, to the class] code having to do it.

as i said, those coordinate transforms (eg. [303,403] to [3,3]) do not magically happen, there's always code somewhere that does exactly that. 


This is normal in for example Delphi and other oop languages and it can be done as an object event or an operating system event. I hope I explained it wrongly!!
this has very little to do with delphi or OOP. it appears that the delphi graphics library you used worked that way. 


please go to wikipedia or do a google search and read up on what a scenegraph is. 
oh, and btw: 

not every graphics library works the same way and if you feel 
comfortable in delphi i suggest you use that, there is absolutely 
no point in using a library were the core concepts colide with 
what you're trying to achieve. 



hope that helps, 
i know no is never a pleasant answer, 
best, 
hansi. 

I'm sure is not this that you want, is it?
warning: lazy code below...

Bota[] b = new Bota[10];

void setup()
{
  size(200,200);
  for (int i=0; i<b.length;i++)
  {
    b[i] = new Bota(i*15, height/2);
  }
}

void draw()
{
  for (int i=0; i<b.length;i++)
  {
    b[i].disp() ;
  }
}


class Bota
{
  int x,y;
  Bota(int _x, int _y)
  {
    x = _x;
    y = _y;

  }
  
  void disp()
  {
    rect(x,y,10,10);
        if(isOver(mouseX,mouseY) && mousePressed)
  {
    
   println("relative x "+where(mouseX,mouseY)+"   abs x "+mouseX);
  }
  
}
  
  boolean isOver(int mx, int my)
  {
    if (mx > x 
        && mx < x+10
        && my > y
        && my < y+10)
      {
        //println("isover");
        return true;
      }
      else
      {
        return false;
      }
  }
  int where(int mmx, int mmy)
  {

      return mmx-x; 

  }
  
}

Thank you kritzikra, I take on board your comments...however

Thank you v.k. the result is exactly what I meant and it achieves exactly.
Being new to Processing, I cannot tell whether the mouse event is truly encapsulated but it does appear to be by looking at the coordinates. Each object should be able to pass back to me its own name, ( or in this case its array position) to prove it is not a generic ( or global) event.

Thank you for your time.
Well Im a self learning and only tried programming in processing, so i can't tell you about encapsulation...
But as the array is constructed out side the class you cant get its id from inside unless you make something like:

Bota (int _x, int _y, int _id)
{}

and calls it passing i as id:

for (i;i<length;i++)
new Bota (i*x, y, i)

... Or making another object that constructs the array of Bota's

class SomeBota
{

}
Thanks v.k.
Yes I was working on this when you replied and came up with the following which displays the name as the mouse hovers...
Proven!!

Bota[] b = new Bota[10];

void setup()
{
  size(200,200);
  for (int i=0; i<b.length;i++)
  {
    b[i] = new Bota(i*15, height/2,i);
  }
}

void draw()
{
  for (int i=0; i<b.length; i++)
  {
    b[i].disp() ;
  }
}


class Bota
{
  int x,y,name;
  Bota(int _x, int _y, int _name)
  {
    x = _x;
    y = _y;
  name=_name;
  }
  
  void disp()
  {
    rect(x,y,10,10);
        if(isOver(mouseX,mouseY,name) && mousePressed)
  {
    
   println("relative x "+where(mouseX,mouseY)+"   abs x "+mouseX);
  }
  
}
  
  boolean isOver(int mx, int my, int name)
  {
    if (mx > x 
        && mx < x+10
        && my > y
        && my < y+10)
      {
        println("isover-"+name);
        return true;
      }
      else
      {
        return false;
      }
  }
  int where(int mmx, int mmy)
  {

      return mmx-x; 

  }
  
}