Merge branch 'elmdnd'

Conflicts:
	trunk/TMP/st/elementary/.gitignore

SVN revision: 51935
This commit is contained in:
Brett Nash 2010-09-07 06:56:16 +00:00
parent 31ed630554
commit 0d492dcdaf
10 changed files with 792 additions and 36 deletions

View File

@ -1,5 +1,5 @@
*.o
*.lo
*.o
*.la
.libs
.deps
@ -30,3 +30,14 @@ elementary_testql
/ltmain.sh
/missing
/stamp-h1
core
cscope.out
doc/elementary.dox
elementary.spec
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
src/lib/Elementary.h
tags

View File

@ -80,7 +80,8 @@ test_multi.c \
test_floating.c \
test_launcher.c \
test_anim.c \
test_calendar.c
test_calendar.c \
test_drag.c
elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la @ELEMENTARY_EWEATHER_LIBS@
elementary_test_LDFLAGS =

View File

@ -81,6 +81,9 @@ void test_launcher2(void *data, Evas_Object *obj, void *event_info);
void test_launcher3(void *data, Evas_Object *obj, void *event_info);
void test_anim(void *data, Evas_Object *obj, void *event_info);
void test_drag_source(void *data, Evas_Object *obj, void *event_info);
void test_drag_dest(void *data, Evas_Object *obj, void *event_info);
void test_drag_genlist(void *data, Evas_Object *obj, void *event_info);
struct elm_test
{
@ -202,6 +205,10 @@ my_win_main(void)
tests = NULL;
#define ADD_TEST(name_, cb_) elm_test_add(&tests, name_, cb_)
ADD_TEST("Drag Source", test_drag_source);
ADD_TEST("Drag Destination", test_drag_dest);
ADD_TEST("Drag GenList", test_drag_genlist);
ADD_TEST("Bg Plain", test_bg_plain);
ADD_TEST("Bg Image", test_bg_image);
ADD_TEST("Icon Transparent", test_icon);

View File

@ -0,0 +1,187 @@
#include <stdbool.h>
#include <Ecore_X.h>
#include <Elementary.h>
#include "elm_priv.h"
/* nash: I have NFI what this does: Just copying the other tests */
#ifndef ELM_LIB_QUICKLAUNCH
#define IM "/home/nash/work/samsung/autopaste/images/"
static const char *images[] = {
IM "cow.jpg",
IM "img_3104.jpg",
IM"xmas.jpg",
IM"river.jpg"
};
#define N_IMAGES 4
void
test_drag_source(void *data, Evas_Object *obj, void *eventinfo){
Evas_Object *win, *bg, *bx, *ph, *ctrls;
int i;
win = elm_win_add(NULL, "drag", ELM_WIN_BASIC);
elm_win_title_set(win, "Drag Source");
elm_win_autodel_set(win, 1);
bg = elm_bg_add(win);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bg);
evas_object_show(bg);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bx);
evas_object_show(bx);
ctrls = elm_box_add(win);
elm_box_horizontal_set(ctrls, true);
evas_object_size_hint_weight_set(ctrls, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(ctrls, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, ctrls);
evas_object_show(ctrls);
for (i = 0 ; i < N_IMAGES ; i ++){
ph = elm_photo_add(win);
elm_photo_file_set(ph, images[i]);
evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND,
EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(ph, EVAS_HINT_FILL,
EVAS_HINT_FILL);
elm_photo_size_set(ph, 80);
elm_box_pack_end(ctrls, ph);
evas_object_show(ph);
// evas_object_data_set(ph,"URI",images[i]);
// evas_object_smart_callback_add(ph, "clicked",
// on_select_image, ph);
}
evas_object_size_hint_min_set(bg, 468, 160);
evas_object_resize(win, 320, 320);
evas_object_show(win);
}
static Eina_Bool
_dnd_enter(void *data, int etype, void *ev){
printf("enter\n");
return true;
}
static Eina_Bool
_dnd_leave(void *data, int etype, void *ev){
printf("leave\n");
return true;
}
static Eina_Bool
_dnd_position(void *data, int etype, void *ev){
struct _Ecore_X_Event_Xdnd_Position *pos;
Ecore_X_Rectangle rect;
pos = ev;
printf("position: %3d,%3d, Action: %s\n",
pos->position.x,pos->position.y,
ecore_x_atom_name_get(pos->action));
/* Need to send a status back */
rect.x = pos->position.x - 5;
rect.y = pos->position.y - 5;
rect.width = 10;
rect.height = 10;
ecore_x_dnd_send_status(true, false, rect, pos->action);
return true;
}
static Eina_Bool
_dnd_status(void *data, int etype, void *ev){
printf("status\n");
return true;
}
Evas_Object *en;
static Eina_Bool
_dnd_drop(void *data, int etype, void *ev){
struct _Ecore_X_Event_Xdnd_Drop *drop;
bool rv;
drop = ev;
printf("Drop: %3d,%3d, Action: %s\n",
drop->position.x,drop->position.y,
ecore_x_atom_name_get(drop->action));
rv = elm_selection_get(ELM_SEL_XDND, ELM_SEL_MARKUP, en);
if (rv != true){
printf("Selection set fail\n");
}
return true;
}
static Eina_Bool
_dnd_finish(void *data, int etype, void *ev){
printf("finish\n");
return true;
}
void
test_drag_dest(void *data, Evas_Object *obj, void *event){
Evas_Object *win, *bg, *bx;
Ecore_Evas *ee;
Ecore_X_Window xwin;
win = elm_win_add(NULL, "drag", ELM_WIN_BASIC);
elm_win_title_set(win, "Drag Destination");
elm_win_autodel_set(win, 1);
bg = elm_bg_add(win);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bg);
evas_object_show(bg);
evas_object_size_hint_min_set(bg, 160, 160);
evas_object_resize(win, 480, 150);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bx);
evas_object_show(bx);
en = elm_entry_add(win);
elm_entry_line_wrap_set(en, 0);
elm_entry_entry_set(en,"Your mum!");
evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, en);
evas_object_show(en);
printf("Adding events\n");
ecore_event_handler_add(ECORE_X_EVENT_XDND_ENTER, _dnd_enter, NULL);
ecore_event_handler_add(ECORE_X_EVENT_XDND_POSITION, _dnd_position, NULL);
ecore_event_handler_add(ECORE_X_EVENT_XDND_STATUS, _dnd_status, NULL);
ecore_event_handler_add(ECORE_X_EVENT_XDND_LEAVE, _dnd_leave, NULL);
ecore_event_handler_add(ECORE_X_EVENT_XDND_DROP, _dnd_drop, NULL);
ecore_event_handler_add(ECORE_X_EVENT_XDND_FINISHED, _dnd_finish, NULL);
printf("Enabled DND\n");
ee = ecore_evas_ecore_evas_get(evas_object_evas_get(win));
xwin = (Ecore_X_Window)ecore_evas_window_get(ee);
ecore_x_dnd_aware_set(xwin, true);
evas_object_show(win);
}
void
test_drag_genlist(void *data, Evas_Object *obj, void *event){
printf("No genlist yet\n");
}
#endif

View File

@ -579,7 +579,7 @@ my_ent_bt_pas(void *data, Evas_Object *obj, void *event_info)
void
test_entry3(void *data, Evas_Object *obj, void *event_info)
{
Evas_Object *win, *bg, *bx, *bx2, *bt, *en, *en_p, *sp;
Evas_Object *win, *bg, *bx, *bx2, *bt, *en;
win = elm_win_add(NULL, "entry3", ELM_WIN_BASIC);
elm_win_title_set(win, "Entry 3");
@ -1206,7 +1206,7 @@ test_entry4(void *data, Evas_Object *obj, void *event_info)
void
test_entry5(void *data, Evas_Object *obj, void *event_info)
{
Evas_Object *win, *bg, *bx, *bx2, *bt, *en, *en_p, *sp;
Evas_Object *win, *bg, *bx, *bx2, *bt, *en;
win = elm_win_add(NULL, "entry5", ELM_WIN_BASIC);
elm_win_title_set(win, "Entry 5");

View File

@ -123,7 +123,7 @@ test_gengrid(void *data, Evas_Object *obj, void *event_info)
{
Evas_Object *win, *bg, *grid;
static Testitem ti[144];
int i, j, n;
int i, n;
char buf[PATH_MAX];
const char *img[9] =
{

View File

@ -105,7 +105,7 @@ static Eina_Bool external_notify_param_set(void *data __UNUSED__,
&& param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
{
Elm_Notify_Orient set = _orient_get(param->s);
if (set == ELM_NOTIFY_ORIENT_LAST) return;
if (set == ELM_NOTIFY_ORIENT_LAST) return EINA_FALSE;
elm_notify_orient_set(obj, set);
return EINA_TRUE;
}

View File

@ -1,4 +1,5 @@
#include <stdbool.h>
#include <sys/mman.h>
#include <stdio.h> // debug
@ -26,6 +27,7 @@
enum {
CNP_ATOM_TARGETS = 0,
CNP_ATOM_text_uri,
CNP_ATOM_text_urilist,
CNP_ATOM_image_png,
CNP_ATOM_XELM,
CNP_ATOM_text_html_utf8,
@ -118,6 +120,8 @@ static int notify_handler_png(struct _elm_cnp_selection *sel,
static int notify_handler_uri(struct _elm_cnp_selection *sel,
Ecore_X_Event_Selection_Notify *notify);
static struct pasteimage *pasteimage_alloc(const char *file);
static bool pasteimage_append(struct pasteimage *pi, Evas_Object *entry);
static struct {
const char *name;
@ -153,9 +157,17 @@ static struct {
notify_handler_uri,
0
},
[CNP_ATOM_text_urilist] = {
"text/uri-list",
ELM_SEL_IMAGE | ELM_SEL_MARKUP,
uri_converter,
NULL,
notify_handler_uri,
0
},
[CNP_ATOM_image_png] = {
"image/png",
ELM_SEL_IMAGE | ELM_SEL_IMAGE,
ELM_SEL_IMAGE,
png_converter,
NULL,
notify_handler_png,
@ -240,9 +252,24 @@ static struct _elm_cnp_selection selections[ELM_SEL_MAX] = {
.set = ecore_x_selection_clipboard_set,
.clear = ecore_x_selection_clipboard_clear,
.request = ecore_x_selection_clipboard_request,
}
},
ARRAYINIT(ELM_SEL_XDND) {
.debug = "XDnD",
.ecore_sel = ECORE_X_SELECTION_XDND,
.request = ecore_x_selection_xdnd_request,
},
};
/* Data for DND in progress */
/* FIXME: BEtter name */
struct {
int ntypes;
const char **types;
unsigned int textreq: 1;
struct pasteimage *pi;
int x,y;
} savedtypes = { 0, NULL, 0, NULL, 0, 0 };
static int _elm_cnp_init_count = 0;
/* Gah... who left this out of XAtoms.h */
static Ecore_X_Atom clipboard_atom;
@ -250,6 +277,8 @@ static Ecore_X_Atom clipboard_atom;
Eina_List *pastedimages;
#endif
/* Stringshared, so I can just compare pointers later */
static const char *text_uri;
Eina_Bool
elm_selection_set(enum _elm_sel_type selection, Evas_Object *widget,
@ -319,7 +348,7 @@ elm_selection_get(enum _elm_sel_type selection, enum _elm_sel_format format,
sel->requestformat = format;
sel->requestwidget = widget;
sel->request(elm_win_xwindow_get(top), ECORE_X_SELECTION_TARGET_UTF8_STRING);
sel->request(elm_win_xwindow_get(top), ECORE_X_SELECTION_TARGET_TARGETS);
return EINA_TRUE;
#else
@ -345,7 +374,9 @@ _elm_cnp_init(void){
ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, selection_clear,NULL);
ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,selection_notify,NULL);
return EINA_TRUE;
text_uri = eina_stringshare_add("text/uri-list");
return EINA_TRUE;
}
static Eina_Bool
@ -433,6 +464,9 @@ selection_notify(void *udata __UNUSED__, int type __UNUSED__, void *event){
case ECORE_X_SELECTION_SECONDARY:
sel = selections + ELM_SEL_SECONDARY;
break;
case ECORE_X_SELECTION_XDND:
sel = selections + ELM_SEL_XDND;
break;
default:
return ECORE_CALLBACK_PASS_ON;
}
@ -486,11 +520,12 @@ targets_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
}
static int
png_converter(char *target __UNUSED__, void *data __UNUSED__, int size __UNUSED__,
png_converter(char *target __UNUSED__, void *data, int size,
void **data_ret __UNUSED__, int *size_ret __UNUSED__,
Ecore_X_Atom *ttype __UNUSED__, int *typesize __UNUSED__)
{
return 1;
cnp_debug("Png converter called\n");
return 1;
}
/*
@ -582,7 +617,9 @@ notify_handler_text(struct _elm_cnp_selection *sel,
char *str;
data = notify->data;
cnp_debug("Notify handler text %d %d %p\n",data->format,data->length,data->data);
str = mark_up((char*)data->data, NULL);
cnp_debug("String is %s (from %s)\n",str,data->data);
elm_entry_entry_insert(sel->requestwidget, str);
free(str);
@ -598,30 +635,60 @@ notify_handler_uri(struct _elm_cnp_selection *sel,
Ecore_X_Event_Selection_Notify *notify)
{
Ecore_X_Selection_Data *data;
Ecore_X_Selection_Data_Files *files;
struct pasteimage *pi;
char entrytag[100];
char *p;
data = notify->data;
p = (char *)data->data;
printf("data->format is %d %p %p\n",data->format,notify,data);
if (data->content == ECORE_X_SELECTION_CONTENT_FILES)
{
cnp_debug("got a files list\n");
files = notify->data;
if (files->num_files > 1)
{
/* Don't handle many items */
cnp_debug("more then one file: Bailing\n");
return 0;
}
p = files->files[0];
}
else
p = (char *)data->data;
if (!p)
{
cnp_debug("Couldn't find a file\n");
return 0;
}
cnp_debug("Got %s\n",p);
if (strncmp(p,"file://",7) != 0){
cnp_debug("Doesn't start with ;file; %s\n",p);
if (strncmp(p,"file://",7) != 0)
{
cnp_debug("Doesn't start with ;file; %s\n",p);
return 0;
}
}
p += strlen("file://");
pi = calloc(1,sizeof(struct pasteimage));
snprintf(entrytag, sizeof(entrytag), "pasteimage-%p",pi);
pi->tag = strdup(entrytag);
pi->file = strndup(p,data->length - strlen("file://"));
if (!strstr(p,"png"))
{
/* FIXME: Better test: Load it in evasw & see is probably best */
cnp_debug("No png, ignoring\n");
if (savedtypes.textreq) savedtypes.textreq = 0;
return 0;
}
elm_entry_item_provider_append(sel->requestwidget, image_provider, pi);
pastedimages = eina_list_append(pastedimages, pi);
pi = pasteimage_alloc(p);
snprintf(entrytag, sizeof(entrytag), "<item absize=240x180 href=%s>",pi->tag);
elm_entry_entry_insert(sel->requestwidget, entrytag);
if (savedtypes.textreq)
{
savedtypes.textreq = 0;
savedtypes.pi = pi;
}
else
{
pasteimage_append(pi, sel->requestwidget);
savedtypes.pi = NULL;
}
return 0;
}
@ -630,7 +697,64 @@ static int
notify_handler_png(struct _elm_cnp_selection *sel __UNUSED__,
Ecore_X_Event_Selection_Notify *notify __UNUSED__)
{
Ecore_X_Selection_Data *data;
char *fname,*tmppath;
struct pasteimage *pi;
int fd,len;
void *map;
cnp_debug("got a png!\n");
data = notify->data;
cnp_debug("Size if %d\n",data->length);
/* generate tmp name */
tmppath = getenv("TMP");
if (!tmppath) tmppath = P_tmpdir;
if (!tmppath) tmppath = "/tmp";
len = snprintf(NULL,0,"%s/%sXXXXXX",tmppath, "elmcnpimage-");
if (len < 0) return 1;
len ++;
fname = malloc(len);
if (!fname) return 1;
len = snprintf(fname,len,"%s/%sXXXXXX",tmppath, "elmcnpimage-");
fd = mkstemp(fname);
if (fd < 0)
{
free(fname);
return 1;
}
if (ftruncate(fd, data->length))
{
perror("ftruncate");
unlink(fname);
free(fname);
close(fd);
}
map = mmap(NULL,data->length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
perror("mmap");
unlink(fname);
free(fname);
close(fd);
}
memcpy(map, data->data, data->length);
munmap(map,data->length);
close(fd);
/* FIXME: add clean up function */
// on_exit: file name + pid
// need pid, as forked children inheret list :-(
/* FIXME: Add to paste image data to clean up */
pi = pasteimage_alloc(fname);
pasteimage_append(pi, sel->requestwidget);
return 0;
}
@ -642,11 +766,9 @@ text_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
{
struct _elm_cnp_selection *sel;
cnp_debug("text converter\n");
sel = selections + *(int *)data;
if (!sel->active)
{
return 1;
}
if (!sel->active) return 1;
if (sel->format == ELM_SEL_MARKUP){
*data_ret = remove_tags(sel->selbuf, size_ret);
@ -662,8 +784,8 @@ text_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
}
static int
edje_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
void **data_ret, int *size_ret, Ecore_X_Atom *ttype __UNUSED__,
edje_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
void **data_ret, int *size_ret, Ecore_X_Atom *ttype __UNUSED__,
int *typesize __UNUSED__)
{
struct _elm_cnp_selection *sel;
@ -677,8 +799,8 @@ edje_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
static int
html_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
void **data_ret, int *size_ret, Ecore_X_Atom *ttype __UNUSED__,
html_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
void **data_ret, int *size_ret, Ecore_X_Atom *ttype __UNUSED__,
int *typesize __UNUSED__)
{
struct _elm_cnp_selection *sel;
@ -691,8 +813,8 @@ html_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
}
static int
uri_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
void **data_ret, int *size_ret, Ecore_X_Atom *ttype __UNUSED__,
uri_converter(char *target __UNUSED__, void *data, int size __UNUSED__,
void **data_ret, int *size_ret, Ecore_X_Atom *ttype __UNUSED__,
int *typesize __UNUSED__)
{
struct _elm_cnp_selection *sel;
@ -734,6 +856,56 @@ image_provider(void *images __UNUSED__, Evas_Object *entry, const char *item)
return NULL;
}
static struct pasteimage *
pasteimage_alloc(const char *file)
{
struct pasteimage *pi;
int len;
char *buf;
pi = calloc(1,sizeof(struct pasteimage));
if (!pi) return NULL;
len = snprintf(NULL, 0, "pasteimage-%p",pi);
len ++;
buf = malloc(len);
if (!buf)
{
free(pi);
return NULL;
}
snprintf(buf, len, "pasteimage-%p",pi);
pi->tag = buf;
if (file)
{
if (strstr(file,"file://")) file += strlen("file://");
pi->file = strdup(file);
}
return pi;
}
static bool
pasteimage_append(struct pasteimage *pi, Evas_Object *entry)
{
char entrytag[100];
if (!pi) return false;
if (!entry) return false;
/* FIXME: Need to do this per widget */
if (!pastedimages)
elm_entry_item_provider_append(entry, image_provider, NULL);
pastedimages = eina_list_append(pastedimages, pi);
snprintf(entrytag, sizeof(entrytag),"<item absize=240x180 href=%s>",pi->tag);
elm_entry_entry_insert(entry, entrytag);
return true;
}
static void
entry_deleted(void *images __UNUSED__, Evas *e __UNUSED__, Evas_Object *entry, void *unused __UNUSED__)
{
@ -836,4 +1008,302 @@ mark_up(const char *start, int *lenp){
}
/**
* Drag & Drop functions
*/
struct dropable {
Evas_Object *obj;
/* FIXME: Cache window */
int types; /* FIXME */
elm_drop_cb dropcb;
void *cbdata;
};
/* FIXME: Way too many globals */
Eina_List *drops = NULL;
Evas_Object *en;
Ecore_Event_Handler *handler_pos, *handler_drop, *handler_enter;
struct dropable *cur;
static Eina_Bool
_dnd_enter(void *data, int etype, void *ev)
{
Ecore_X_Event_Xdnd_Enter *enter = ev;
int i;
/* Skip it */
if (enter->num_types == 0 || enter->types == NULL) return true;
cnp_debug("Types\n");
savedtypes.ntypes = enter->num_types;
if (savedtypes.types) free(savedtypes.types);
savedtypes.types = malloc(sizeof(char *) * enter->num_types);
for (i = 0 ; i < enter->num_types ; i ++)
{
savedtypes.types[i] = eina_stringshare_add(enter->types[i]);
cnp_debug("Type is %s %p %p\n",enter->types[i],
savedtypes.types[i],text_uri);
if (savedtypes.types[i] == text_uri)
{
/* Request it, so we know what it is */
cnp_debug("Sending uri request\n");
savedtypes.textreq = 1;
savedtypes.pi = NULL; /* FIXME: Free? */
ecore_x_selection_xdnd_request(enter->win, text_uri);
}
}
/* FIXME: Find an object and make it current */
return true;
}
static Eina_Bool
_dnd_drop(void *data, int etype, void *ev)
{
struct _Ecore_X_Event_Xdnd_Drop *drop;
struct dropable *dropable;
Eina_List *l;
Evas_Object *elmwin;
Ecore_X_Window xwin;
Elm_Drop_Data ddata;
int x,y,w,h;
int i,j;
drop = ev;
// check we still have something to drop
if (!drops) return true;
/* Find any widget in our window; then work out geometry rel to our window */
for (l = drops ; l ; l = l->next)
{
dropable = l->data;
xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(
evas_object_evas_get(
dropable->obj)));
if (xwin == drop->win)
break;
}
/* didn't find a window */
if (l == NULL)
return true;
/* Calculate real (widget relative) position */
// - window position
// - widget position
elmwin = elm_object_top_widget_get(dropable->obj);
elm_win_screen_position_get(elmwin, &x, &y);
savedtypes.x = drop->position.x - x;
savedtypes.y = drop->position.y - y;
printf("Drop position is %d,%d\n",savedtypes.x,savedtypes.y);
for ( ; l ; l = l->next)
{
dropable = l->data;
evas_object_geometry_get(dropable->obj, &x, &y, &w, &h);
if (savedtypes.x >= x && savedtypes.y >= y &&
savedtypes.x < x + w && savedtypes.y < y + h)
break; /* found! */
}
if (!l) /* didn't find one */
return true;
evas_object_geometry_get(dropable->obj, &x, &y, NULL, NULL);
savedtypes.x -= x;
savedtypes.y -= y;
/* Find our type from the previous list */
for (i = 0 ; i < CNP_N_ATOMS ; i ++)
{
for (j = 0 ; j < savedtypes.ntypes ; j ++)
{
if (strcmp(savedtypes.types[j], atoms[i].name) == 0)
{
goto found;
}
}
}
cnp_debug("Didn't find a target\n");
return true;
found:
printf("Found a target we'd like: %s\n",atoms[i].name);
cnp_debug("0x%x\n",xwin);
if (i == CNP_ATOM_text_urilist)
{
printf("We found a URI...\n");
if (savedtypes.pi)
{
char entrytag[100];
/* FIXME: Paste immediately */
cnp_debug("paste immediately\n");
// pasteimage_append(savedtypes.pi, dropable->obj);
ddata.x = savedtypes.x;
ddata.y = savedtypes.y;
ddata.format = ELM_SEL_IMAGE;
/* FIXME: Need to do this per widget */
if (!pastedimages)
elm_entry_item_provider_append(dropable->obj, image_provider, NULL);
pastedimages = eina_list_append(pastedimages, savedtypes.pi);
snprintf(entrytag, sizeof(entrytag),"<item absize=240x180 href=%s>",savedtypes.pi->tag);
ddata.data = entrytag;
cnp_debug("Insert %s\n",(char *)ddata.data);
dropable->dropcb(dropable->cbdata, dropable->obj, &ddata);
ecore_x_dnd_send_finished();
return true;
}
else if (savedtypes.textreq)
{
/* Already asked: Pretend we asked now, and paste imediately when
* it comes in */
savedtypes.textreq = 0;
ecore_x_dnd_send_finished();
return true;
}
}
selections[ELM_SEL_XDND].requestwidget = dropable->obj;
selections[ELM_SEL_XDND].requestformat = ELM_SEL_MARKUP;
selections[ELM_SEL_XDND].active = true;
ecore_x_selection_xdnd_request(xwin, atoms[i].name);
return true;
}
static Eina_Bool
_dnd_position(void *data, int etype, void *ev){
struct _Ecore_X_Event_Xdnd_Position *pos;
Ecore_X_Rectangle rect;
pos = ev;
printf("position: %3d,%3d, Action: %s\n",
pos->position.x,pos->position.y,
ecore_x_atom_name_get(pos->action));
/* Need to send a status back */
rect.x = pos->position.x - 5;
rect.y = pos->position.y - 5;
rect.width = 10;
rect.height = 10;
ecore_x_dnd_send_status(true, false, rect, pos->action);
return true;
}
/**
* Add a widget as drop target.
*/
Eina_Bool
elm_drop_target_add(Evas_Object *obj, enum _elm_sel_type format,
elm_drop_cb dropcb, void *cbdata)
{
struct dropable *drop;
Ecore_X_Window xwin;
int first;
printf("Adding %p as a drop target\n",obj);
if (!obj) return false;
if (!_elm_cnp_init_count) _elm_cnp_init();
/* Is this the first? */
first = (drops == NULL) ? 1 : 0;
printf("Is first: %d\n",first);
drop = calloc(1,sizeof(struct dropable));
if (!drop) return false;
drop->dropcb = dropcb;
drop->cbdata = cbdata;
/* FIXME: Check it's not already there */
/* FIXME: Check for eina's deranged error method */
drops = eina_list_append(drops, drop);
if (!drops/* || or other error */)
{
free(drop);
return false;
}
drop->obj = obj;
/* Something for now */
drop->types = 1;
evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
/* I love C and varargs */
(Evas_Object_Event_Cb)elm_drop_target_del,
obj);
/* FIXME: Handle resizes */
/* If not the first: We're done */
if (!first) return true;
printf("Enabling DND\n");
xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(
evas_object_evas_get(obj)));
ecore_x_dnd_aware_set(xwin, true);
printf("Adding drop target calls\n");
handler_enter = ecore_event_handler_add(ECORE_X_EVENT_XDND_ENTER,
_dnd_enter, NULL);
handler_pos = ecore_event_handler_add(ECORE_X_EVENT_XDND_POSITION, _dnd_position, NULL);
handler_drop = ecore_event_handler_add(ECORE_X_EVENT_XDND_DROP, _dnd_drop, NULL);
return true;
}
Eina_Bool
elm_drop_target_del(Evas_Object *obj){
struct dropable *drop,*del;
Eina_List *item,*tmp;
Ecore_X_Window xwin;
del = NULL;
EINA_LIST_FOREACH_SAFE(drops, item, tmp, drop)
{
if (drop->obj == obj)
{
drops = eina_list_remove_list(drops, tmp);
del = drop;
break;
}
}
if (!del) return false;
evas_object_event_callback_del(obj, EVAS_CALLBACK_FREE,
(Evas_Object_Event_Cb)elm_drop_target_del);
free(drop);
/* If still drops there: All fine.. continue */
if (drops != NULL) return true;
printf("Disabling DND\n");
xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(
evas_object_evas_get(obj)));
ecore_x_dnd_aware_set(xwin, false);
printf("Adding drop target calls\n");
ecore_event_handler_del(handler_pos);
ecore_event_handler_del(handler_drop);
return true;
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
#endif

View File

@ -121,6 +121,7 @@ struct _Widget_Data
Eina_Bool deferred_cur : 1;
Eina_Bool disabled : 1;
Eina_Bool context_menu : 1;
Eina_Bool drag_selection_asked : 1;
};
struct _Elm_Entry_Context_Menu_Item
@ -141,6 +142,8 @@ struct _Elm_Entry_Item_Provider
};
static const char *widtype = NULL;
static Eina_Bool _drag_drop_cb(void *data, Evas_Object *obj, Elm_Drop_Data *);
static void _del_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _disable_hook(Evas_Object *obj);
@ -1185,7 +1188,8 @@ _event_selection_notify(void *data, int type __UNUSED__, void *event)
Widget_Data *wd = elm_widget_data_get(data);
Ecore_X_Event_Selection_Notify *ev = event;
if (!wd) return ECORE_CALLBACK_PASS_ON;
if (!wd->selection_asked) return ECORE_CALLBACK_PASS_ON;
if (!wd->selection_asked && !wd->drag_selection_asked)
return ECORE_CALLBACK_PASS_ON;
if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
(ev->selection == ECORE_X_SELECTION_PRIMARY))
@ -1208,6 +1212,30 @@ _event_selection_notify(void *data, int type __UNUSED__, void *event)
}
wd->selection_asked = EINA_FALSE;
}
else if (ev->selection == ECORE_X_SELECTION_XDND)
{
Ecore_X_Selection_Data_Text *text_data;
text_data = ev->data;
if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
{
if (text_data->text)
{
char *txt = _text_to_mkup(text_data->text);
if (txt)
{
/* Massive FIXME: this should be at the drag point */
elm_entry_entry_insert(data, txt);
free(txt);
}
}
}
wd->drag_selection_asked = EINA_FALSE;
ecore_x_dnd_send_finished();
}
return ECORE_CALLBACK_PASS_ON;
}
@ -1227,6 +1255,30 @@ _event_selection_clear(void *data __UNUSED__, int type __UNUSED__, void *event _
return 1;*/
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_drag_drop_cb(void *data, Evas_Object *obj, Elm_Drop_Data *drop)
{
Widget_Data *wd;
Eina_Bool rv;
wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
printf("Inserting at (%d,%d) %s\n",drop->x,drop->y,(char*)drop->data);
edje_object_part_text_cursor_copy(wd->ent, "elm.text",
EDJE_CURSOR_MAIN,/*->*/EDJE_CURSOR_USER);
rv = edje_object_part_text_cursor_coord_set(wd->ent,"elm.text",
EDJE_CURSOR_MAIN,drop->x,drop->y);
if (!rv) printf("Warning: Failed to position cursor: paste anyway\n");
elm_entry_entry_insert(obj, drop->data);
edje_object_part_text_cursor_copy(wd->ent, "elm.text",
EDJE_CURSOR_USER,/*->*/EDJE_CURSOR_MAIN);
return EINA_TRUE;
}
#endif
static Evas_Object *
@ -1347,6 +1399,8 @@ elm_entry_add(Evas_Object *parent)
ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR,
_event_selection_clear, obj);
}
elm_drop_target_add(obj, ELM_SEL_IMAGE | ELM_SEL_MARKUP,_drag_drop_cb, NULL);
#endif
entries = eina_list_prepend(entries, obj);
@ -1628,6 +1682,12 @@ elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
elm_entry_entry_set(obj, t);
eina_stringshare_del(t);
_sizing_eval(obj);
if (editable)
elm_drop_target_add(obj, ELM_SEL_IMAGE | ELM_SEL_MARKUP,
_drag_drop_cb, NULL);
else
elm_drop_target_del(obj);
}
/**
@ -2167,3 +2227,7 @@ elm_entry_utf8_to_markup(const char *s)
if (!ss) ss = strdup("");
return ss;
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/

View File

@ -109,6 +109,7 @@ enum _elm_sel_type {
ELM_SEL_PRIMARY,
ELM_SEL_SECONDARY,
ELM_SEL_CLIPBOARD,
ELM_SEL_XDND,
ELM_SEL_MAX,
};
@ -218,9 +219,24 @@ void _elm_config_init(void);
void _elm_config_sub_init(void);
void _elm_config_shutdown(void);
/* FIXME: nash formatiing */
typedef struct Elm_Drop_Data {
int x,y;
enum _elm_sel_format format;
void *data;
int len;
} Elm_Drop_Data;
typedef Eina_Bool (*elm_drop_cb)(void *, Evas_Object *, Elm_Drop_Data *data);
Eina_Bool elm_selection_set(enum _elm_sel_type selection, Evas_Object *widget, enum _elm_sel_format format, const char *buf);
Eina_Bool elm_selection_clear(enum _elm_sel_type selection, Evas_Object *widget);
Eina_Bool elm_selection_get(enum _elm_sel_type selection, enum _elm_sel_format format, Evas_Object *widget);
/* FIXME: Need a typedef for the callback */
Eina_Bool elm_drop_target_add(Evas_Object *widget,
enum _elm_sel_type, elm_drop_cb, void *);
Eina_Bool elm_drop_target_del(Evas_Object *widget);
Eina_Bool _elm_dangerous_call_check(const char *call);