On 22.01.2018 14:07 Karl Harbinger wrote:
[actual code elided]
> Okay, this seems to do the trick.
Yes, AFAICT it does. But there are several things you can and *should*
improve. This is not real production code, is it?
Here are some thoughts (together with your code):
You really don't need to "waste" a callback for what you intend to do.
Admitted, there is no need for a callback if you derive from Fl_Box, but
anyway. More than that, your callback creates a memory leak and degrades
performance:
static void mouse_over_box_cb(Fl_Widget *o, void *v) {
mouse_over_box *b = (mouse_over_box *)o;
const char *img = (mouse_over == 0) ? (const char *)v : NULL;
b->image(new Fl_PNG_Image(img));
The statement above creates a new Fl_PNG_Image every time the mouse
enters the widget. The previous image is never deleted. The image is
always read from disk (unless you use an in-memory image in real code).
You can work around this by using Fl_Shared_Image to leave the caching
of the image(s) to the FLTK library:
if (img) // don't forget this if() !
b->image(Fl_Shared_Image::get(img)); // use Fl_Shared_Image
else
b->image(img); // NULL
But I wouldn't do this. Since you are subclassing anyway you can also
add another image variable and do everything you need in the handle()
method. Note: code is untested!
class mouse_over_box : public Fl_Box
{
public:
mouse_over_box(int X, int Y, int W, int H, const char *L=0)
: Fl_Box(X, Y, W, H, L),
: mouse_over_image(0)
{ }
virtual ~mouse_over_box() { }
Fl_Image *mouse_over_image;
int handle(int event) {
int ret = Fl_Box::handle(event);
switch (event) {
case FL_ENTER:
fl_cursor(FL_CURSOR_HAND);
image(mouse_over_image);
parent()->redraw();
break;
case FL_LEAVE:
fl_cursor(FL_CURSOR_DEFAULT);
image(0);
parent()->redraw();
break;
}
return ret;
}
};
/* ... */
mouse_over_box *box = new mouse_over_box(x, y, w, h);
box->mouse_over_image = new Fl_PNG_Image("button.png");
box->clear_visible_focus();
Note that you don't need a global variable and no callback. The image is
allocated only once and doesn't need to be deleted, but if you use
several images in several such boxes it may be good to delete the image
in the d'tor (take care if you share images - you may also want to use
Fl_Shared_Image and Fl_Shared_Image::release() in the d'tor).