Use button.mouseOver inside a class

Hello. I’, trying to wrap a p5 button in a class to make a different look.
But I can’t make the listener to work, I think is a scope problem with my callback function atempt. Easy to understand by looking at the code.
I thought in extending p5.Element, but I can’t figure out how to deal with the fact that the button is created with createButton() and not new Button, no way I could make the super() call that machines were happy, so I did this pointer to the p5.Element inside my class. It looks wrong to me though…
edit: the log from inside the function works, but not the assignment to class field.
This is where I am.

let b1;
function setup() {
  createCanvas(400, 400);
  b1 = new Gbutton("the_message", 100, 100, cb);
}

function draw() {
  background(220);
  b1.show();
}
function cb() {}

class Gbutton {
  constructor(msg, x, y, callback) {
    this.bt = createButton(msg);
    this.x = x;
    this.y = y;
    this.w = 180;
    this.h = 24;
    this.callback = callback;
    this.font_size = 19;
    this.font_color = color(180, 180, 180);
    this.color = color(180, 180, 180);
    this.bt.position(x, y);
    this.bt.style("opacity", 0.0);
    this.bt.mouseOver(this.m_o);
  }

  show() {
    push();
    noStroke();
    rectMode(CENTER);
    textSize(30);
    textAlign(CENTER, CENTER);
    fill(this.font_color);
    text(this.bt.elt.innerText, this.x, this.y);
    pop();
  }

  m_o() {
    console.log(this.font_color); //undefined?
    this.font_color = color(255, 0, 255);
    console.log(this.font_color); // the correct object, but the color don't change
    // a scope problem I guess..
  }
}

it’s online here in editor.p5js.org:

thanks

By default the keyword this inside a function refers to the object that had invoked that function.

B/c m_o() is called back by a p5.Element object the keyword this inside it points to that object.

For such cases we can clone a function using method bind() w/ its this pointing to a fixed object:
this.bt.mouseOver(this.m_o);this.bt.mouseOver(this.m_o.bind(this));

3 Likes

Lovely! Once more thanks :)))

By the way, just for the sake of understanding, if is not to much to ask, what about the extending approach? Is it possible to do it when the object is created via a factory function?
If this is to much out of the scope here, no problem :wink:
thanks @GoToLoop

If that object is the 1 which is gonna invoke functions, we don’t need to do anything.

1 Like