Basically i'm implementing widgets using custom pixmaps, and the problem that i have is:
I'm connecting handlers for all events MOUSE_IN, MOUSE_OUT, MOUSE_DOWN and MOUSE_UP for an Evas_Object.
What i need to implement for this particular widget (button) is of course that when the mouse button is kept pressed but the pointer moves outside of the widget's area, the image is restored to the unpressed one (as it's the case with basically every GUI toolkit there is).
Now the situation is that after MOUSE_DOWN was called and the mouse button is kept pressed by the user, the MOUSE_IN and MOUSE_OUT events are never being called, and i have no idea how to make the widget receive the appropriate information so it can do the redraw.
Any hints on how to accomplish that, or is this a bug in Evas?
Attached: Source code of the particular widget. Full source of current state is available at http://linux-media.net/walengine-snapshot-1.tar.gz (It requires GLib, Ecore, Evas, libxml2)
#ifndef _EVAS_BUTTON_H_ #define _EVAS_BUTTON_H_
#include <X11/Xlib.h>
#include <Evas.h>
#include <evas_wa3button.h>
#include <loadxml.h>
enum {
WA3BUTTON_STATE_IDLE,
WA3BUTTON_STATE_ACTIVE
};
enum {
WA3BUTTON_TYPE_PUSH,
WA3BUTTON_TYPE_TOGGLE
};
typedef struct _wa3button wa3button;
struct _wa3button {
char *id_container;
char *id_layout;
char *id_normal;
char *id_pressed;
char *id_active;
char *id;
Evas_Object* button;
int btype;
int astate;
int state;
int x;
int y;
int w;
int h;
};
wa3button* wa3button_new(Evas *evas, const char* id, const char* id_container,
const char *id_layout, const char* id_normal, const char* id_pressed, const char
*id_active, int x, int y);
void wa3button_show(wa3button*);
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <Imlib2.h>
#include <Evas.h>
#include "evas_wa3button.h"
#include "loadxml.h"
static void _wa3button_pressed(void* datas, Evas* e, Evas_Object* ob, void*
event_info);
static void _wa3button_release(void* datas, Evas* e, Evas_Object* ob, void*
event_info);
static void _wa3button_mousein(void* data, Evas* e, Evas_Object* ob, void* udata);
static void _wa3button_mouseout(void* data, Evas* e, Evas_Object* ob, void* udata);
static void _wa3button_mousemove(void* data, Evas* e, Evas_Object* ob, void* udata);
wa3button* wa3button_new(Evas* evas,
const char *id,
const char *id_container,
const char *id_layout,
const char *id_normal,
const char *id_pressed,
const char *id_active,
int x,
int y)
{
wa3button *button;
walBitmap *wbmap;
int w, h;
button = g_new0(wa3button,1);
button->button = evas_object_image_add(evas);
wbmap = _walXML_get_bitmap( id_normal);
if (!wbmap) {
#ifdef __DEBUG__
g_message("(EE) UNABLE TO GET <bitmap> id[%s] for <button>
id[%s]", id_normal, id);
#endif
return NULL;
}
imlib_context_push(wbmap->ctx);
w = imlib_image_get_width();
h = imlib_image_get_height();
button->w = w;
button->h = h;
#ifdef __DEBUG__
g_message("(II) NEW <button> id[%s] image[%s] w[%d] h[%d]", id,
id_normal, w, h);
#endif
button->x = x;
button->y = y;
evas_object_image_size_set(button->button, w, h);
evas_object_image_fill_set(button->button, 0, 0, w, h);
evas_object_image_data_copy_set(button->button,
imlib_image_get_data_for_reading_only() );
imlib_context_pop();
button->id_active = g_strdup( id_active);
if ( id_active != NULL) {
button->btype = WA3BUTTON_TYPE_TOGGLE;
button->astate = 0;
} else {
button->btype = WA3BUTTON_TYPE_PUSH;
}
button->id_normal = g_strdup( id_normal);
button->id_pressed = g_strdup( id_pressed);
button->id_container = g_strdup( id_container);
button->id_layout = g_strdup( id_layout);
button->id = g_strdup( id);
return button;
}
void wa3button_show(wa3button* button)
{
evas_object_move(button->button, button->x, button->y);
evas_object_resize(button->button, button->w, button->h);
evas_object_show(button->button);
evas_object_event_callback_add(button->button,EVAS_CALLBACK_MOUSE_DOWN,
_wa3button_pressed, button);
evas_object_event_callback_add(button->button,EVAS_CALLBACK_MOUSE_UP,
_wa3button_release, button);
#if 0
evas_object_event_callback_add(button->button,EVAS_CALLBACK_MOUSE_OUT,
_wa3button_mouseout, button);
evas_object_event_callback_add(button->button,EVAS_CALLBACK_MOUSE_IN,
_wa3button_mousein, button);
#endif
evas_object_event_callback_add(button->button,EVAS_CALLBACK_MOUSE_MOVE,
_wa3button_mousemove, button);
}
static void _wa3button_mousemove(void* data, Evas* e, Evas_Object* ob, void* udata)
{
g_message("move!");
}
static void _wa3button_mousein(void* data, Evas* e, Evas_Object* ob, void* udata)
{
wa3button *button = (wa3button*)data;
walBitmap *wbmap;
g_message("mousein");
if (button->state != WA3BUTTON_STATE_ACTIVE) return;
wbmap = _walXML_get_bitmap( button->id_pressed);
if (!wbmap) {
#ifdef __DEBUG__
g_message("(EE) UNABLE TO GET <bitmap> id[%s] for <button> id[%s]",
button->id_normal, button->id);
#endif
}
imlib_context_push(wbmap->ctx);
evas_object_image_data_copy_set(button->button,
imlib_image_get_data_for_reading_only() );
evas_object_image_data_update_add(button->button, 0, 0, button->w, button->h);
imlib_context_pop();
}
static void _wa3button_mouseout(void* data, Evas* e, Evas_Object* ob, void* udata)
{
wa3button *button = (wa3button*)data;
walBitmap *wbmap;
g_message("mousein");
if (button->state != WA3BUTTON_STATE_ACTIVE) return;
switch (button->btype) {
case WA3BUTTON_TYPE_PUSH:
wbmap = _walXML_get_bitmap( button->id_normal);
break;
case WA3BUTTON_TYPE_TOGGLE:
if (button->astate) {
wbmap = _walXML_get_bitmap( button->id_active);
} else {
wbmap = _walXML_get_bitmap( button->id_normal);
}
break;
}
if (!wbmap) {
#ifdef __DEBUG__
g_message("(EE) UNABLE TO GET <bitmap> id[%s] for <button> id[%s]",
button->id_normal, button->id);
#endif
}
imlib_context_push(wbmap->ctx);
evas_object_image_data_copy_set(button->button,
imlib_image_get_data_for_reading_only() );
evas_object_image_data_update_add(button->button, 0, 0, button->w, button->h);
imlib_context_pop();
}
static void _wa3button_pressed(void* data, Evas* e, Evas_Object* ob, void* udata)
{
wa3button *button = (wa3button*)data;
walBitmap *wbmap;
wbmap = _walXML_get_bitmap( button->id_pressed);
if (!wbmap) {
#ifdef __DEBUG__
g_message("(EE) UNABLE TO GET <bitmap> id[%s] for <button>
id[%s]", button->id_normal, button->id);
#endif
}
imlib_context_push(wbmap->ctx);
evas_object_image_data_copy_set(button->button,
imlib_image_get_data_for_reading_only() );
evas_object_image_data_update_add(button->button, 0, 0, button->w, button->h);
imlib_context_pop();
button->state = WA3BUTTON_STATE_ACTIVE;
}
static void _wa3button_release(void* data, Evas* e, Evas_Object* ob, void* udata)
{
wa3button *button = (wa3button*)data;
walBitmap *wbmap;
switch (button->btype) {
case WA3BUTTON_TYPE_PUSH:
wbmap = _walXML_get_bitmap( button->id_normal);
break;
case WA3BUTTON_TYPE_TOGGLE:
button->astate = (button->astate) ? 0 : 1;
if (button->astate) {
wbmap = _walXML_get_bitmap( button->id_active);
} else {
wbmap = _walXML_get_bitmap( button->id_normal);
}
break;
}
if (!wbmap) {
#ifdef __DEBUG__
g_message("(EE) UNABLE TO GET <bitmap> id[%s] for <button> id[%s]",
button->id_normal, button->id);
#endif
}
imlib_context_push(wbmap->ctx);
evas_object_image_data_copy_set(button->button,
imlib_image_get_data_for_reading_only() );
evas_object_image_data_update_add(button->button, 0, 0, button->w, button->h);
imlib_context_pop();
button->state = WA3BUTTON_STATE_IDLE;
}
