elm fileselector: fix events that must be using Efl.Model objects

Use the new behavior of Efl.Object.event_callback_call to correctly
update events to pass Efl.Model objects while still suppling path
strings for legacy smart callbacks.

Override Elm.Fileselector.event_callback_legacy_call in order to separate
the types of any incoming event call that uses Efl.Model.
This commit is contained in:
Vitor Sousa 2016-08-22 21:59:10 -03:00
parent 0f4cdf7a48
commit 3f5149a675
5 changed files with 194 additions and 95 deletions

View File

@ -25,6 +25,12 @@
/* FIXME: need a way to find a gap between the size of item and thumbnail */
#define GENGRID_PADDING 16
typedef struct _Legacy_Event_Path_Then_Data
{
Eo *eo_obj;
const Efl_Event_Description *evt_desc;
} Legacy_Event_Path_Then_Data;
static Elm_Genlist_Item_Class *list_itc[ELM_FILE_LAST];
static Elm_Gengrid_Item_Class *grid_itc[ELM_FILE_LAST];
@ -39,11 +45,22 @@ EAPI Eina_Error ELM_FILESELECTOR_ERROR_INVALID_MODEL = 0;
static const char ELM_FILESELECTOR_ERROR_UNKNOWN_STR[] = "Unknown Error";
static const char ELM_FILESELECTOR_ERROR_INVALID_MODEL_STR[] = "Model not set";
#define ELM_PRIV_FILESELECTOR_SIGNALS(cmd) \
cmd(SIG_ACTIVATED, "activated", "s") \
cmd(SIG_DIRECTORY_OPEN, "directory,open", "s") \
cmd(SIG_DONE, "done", "s") \
cmd(SIG_SELECTED, "selected", "s") \
cmd(SIG_SELECTED_INVALID, "selected,invalid", "s")
ELM_PRIV_FILESELECTOR_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
ELM_PRIV_FILESELECTOR_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
{SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
{SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
{NULL, NULL}
};
#undef ELM_PRIV_FILESELECTOR_SIGNALS
static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
@ -77,6 +94,21 @@ _model_free_eo_cb(void *data)
efl_unref(eo);
}
void
_event_to_legacy_call(Eo *obj, const Efl_Event_Description *evt_desc, void *event_info)
{
const Efl_Event_Description *legacy_desc = efl_object_legacy_only_event_description_get(evt_desc->name);
efl_event_callback_call(obj, legacy_desc, event_info);
}
void
_model_event_call(Eo *obj, const Efl_Event_Description *evt_desc, Efl_Model *model, const char *path)
{
_event_to_legacy_call(obj, evt_desc, (void *)path);
efl_event_callback_call(obj, evt_desc, model);
}
static void
_monitoring_start(Elm_Fileselector *fs, Elm_Fileselector_Data *sd, Efl_Model *model)
{
@ -623,11 +655,8 @@ _signal_first(Listing_Request *lreq)
sd->multi_selection = eina_list_free(sd->multi_selection);
}
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (lreq->obj, ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN, (void *)lreq->model);
evas_object_smart_callback_call(lreq->obj, "directory,open", (void *)lreq->path);
_model_event_call
(lreq->obj, ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN, lreq->model, lreq->path);
if (!lreq->parent_it)
{
@ -1072,10 +1101,8 @@ _on_item_activated(void *data, const Eo_Event *event)
if (!it_data->is_dir)
{
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (data, ELM_FILESELECTOR_EVENT_ACTIVATED, (void *)it_data->model);
evas_object_smart_callback_call(data, "activated", (void *)it_data->path);
_model_event_call
(data, ELM_FILESELECTOR_EVENT_ACTIVATED, it_data->model, it_data->path);
return;
}
@ -1158,10 +1185,8 @@ _on_item_selected(void *data, const Eo_Event *event)
else
elm_object_text_set(sd->name_entry, it_data->filename);
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (data, EFL_UI_EVENT_SELECTED, (void *)it_data->model);
evas_object_smart_callback_call(data, "selected", (void *)it_data->path);
_model_event_call
(data, EFL_UI_EVENT_SELECTED, it_data->model, it_data->path);
}
else if (sd->multi && it_data->is_dir && sd->double_tap_navigation)
{
@ -1302,9 +1327,7 @@ _ok(void *data, const Eo_Event *event EINA_UNUSED)
if (!sd->model || !sd->path)
{
// EVENTS: should not call legacy
//efl_event_callback_legacy_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL);
evas_object_smart_callback_call(fs, "done", NULL);
_model_event_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL, NULL);
return;
}
@ -1321,10 +1344,8 @@ _ok(void *data, const Eo_Event *event EINA_UNUSED)
selected_model = efl_add(efl_class_get(sd->model), NULL);
_model_str_property_set(selected_model, "path", selection, NULL);
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (fs, ELM_FILESELECTOR_EVENT_DONE, selected_model);
evas_object_smart_callback_call(fs, "done", (void *) selection);
_model_event_call
(fs, ELM_FILESELECTOR_EVENT_DONE, selected_model, selection);
efl_unref(selected_model);
eina_stringshare_del(selection);
@ -1334,15 +1355,14 @@ _ok(void *data, const Eo_Event *event EINA_UNUSED)
Elm_Fileselector_Item_Data *it_data = _selected_item_data_get(sd);
if (it_data)
{
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (fs, ELM_FILESELECTOR_EVENT_DONE, it_data->model);
evas_object_smart_callback_call(fs, "done", (void *) it_data->path);
_model_event_call
(fs, ELM_FILESELECTOR_EVENT_DONE, it_data->model, it_data->path);
}
else
{
_model_event_call
(fs, ELM_FILESELECTOR_EVENT_DONE, sd->model, sd->path);
}
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (fs, ELM_FILESELECTOR_EVENT_DONE, sd->model);
evas_object_smart_callback_call(fs, "done", (void *) sd->path);
}
}
@ -1351,9 +1371,7 @@ _canc(void *data, const Eo_Event *event EINA_UNUSED)
{
Evas_Object *fs = data;
// EVENTS: should not call legacy
//efl_event_callback_legacy_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL);
evas_object_smart_callback_call(fs, "done", NULL);
_model_event_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL, NULL);
}
static void
@ -1388,10 +1406,8 @@ _text_activated_is_dir_then(void *data, void *value)
if (sd->only_folder)
{
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (fs, EFL_UI_EVENT_SELECTED, (void *)model);
evas_object_smart_callback_call(fs, "selected", (void *) str);
_model_event_call
(fs, EFL_UI_EVENT_SELECTED, model, str);
}
}
else
@ -1407,10 +1423,8 @@ _text_activated_is_dir_then(void *data, void *value)
if (sd->only_folder)
{
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (fs, EFL_UI_EVENT_SELECTED, (void *)model);
evas_object_smart_callback_call(fs, "selected", (void *) str);
_model_event_call
(fs, EFL_UI_EVENT_SELECTED, model, str);
}
}
}
@ -1443,18 +1457,14 @@ static void
_on_text_activated_set_path_then_error(void *data, Eina_Error err EINA_UNUSED)
{
Evas_Object *fs = data;
/* Efl_Model *model = efl_key_data_get(fs, _text_activated_model_key); */
Efl_Model *model = efl_key_data_get(fs, _text_activated_model_key);
Eina_Stringshare *str = efl_key_data_get(fs, _text_activated_path_key);
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (fs, EFL_UI_EVENT_SELECTED, (void *)model);
evas_object_smart_callback_call(fs, "selected", (void *)str);
_model_event_call
(fs, EFL_UI_EVENT_SELECTED, model, str);
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (fs, ELM_FILESELECTOR_EVENT_SELECTED_INVALID, (void *)model);
evas_object_smart_callback_call(fs, "selected,invalid", (void *)str);
_model_event_call
(fs, ELM_FILESELECTOR_EVENT_SELECTED_INVALID, model, str);
_text_activated_free_fs_data(fs);
}
@ -2048,6 +2058,98 @@ _elm_fileselector_efl_object_constructor(Eo *obj, Elm_Fileselector_Data *sd)
return obj;
}
static void
_legacy_smart_callback_caller_path_then(void *data, void *value)
{
Legacy_Event_Path_Then_Data *evt_data = data;
_event_to_legacy_call(evt_data->eo_obj, evt_data->evt_desc, value);
free(data);
}
static void
_legacy_smart_callback_caller_path_then_error(void *data, Eina_Error err)
{
ERR("Efl.Model property \"path\" error: %s", eina_error_msg_get(err));
free(data);
}
static Eina_Bool
_from_efl_event_call(Elm_Fileselector *fs, const Efl_Event_Description *evt_desc, Efl_Model *model)
{
Eina_Promise *promise;
Legacy_Event_Path_Then_Data *evt_data;
evt_data = calloc(1, sizeof(Legacy_Event_Path_Then_Data));
evt_data->eo_obj = fs;
evt_data->evt_desc = evt_desc;
// Call legacy smart callback with path
promise = efl_model_property_get(model, "path");
eina_promise_then(promise,
_legacy_smart_callback_caller_path_then,
_legacy_smart_callback_caller_path_then_error,
evt_data);
// Call Eo event with model
return efl_event_callback_call(fs, evt_desc, model);
}
static Eina_Bool
_from_legacy_event_call(Elm_Fileselector *fs, Elm_Fileselector_Data *sd, const Efl_Event_Description *legacy_desc, const Efl_Event_Description *evt_desc, const char *path)
{
const Efl_Class *model_cls = NULL;
if (!sd->model)
model_cls = EIO_MODEL_CLASS;
else
model_cls = efl_class_get(sd->model);
Efl_Model *model = efl_add(model_cls, NULL);
_model_str_property_set(model, "path", path, NULL);
// Call Eo event with model
efl_event_callback_call(fs, evt_desc, model);
efl_unref(model);
// Call legacy smart callback with path
return efl_event_callback_call(fs, legacy_desc, (void *)path);
}
EOLIAN static Eina_Bool
_elm_fileselector_efl_object_event_callback_legacy_call(Eo *obj, Elm_Fileselector_Data *sd,
const Efl_Event_Description *desc, void *event_info)
{
if (desc->legacy_is)
{
const Efl_Event_Description *evt_desc = NULL;
if (strcmp(desc->name, "selected") == 0)
evt_desc = EFL_UI_EVENT_SELECTED;
else if (strcmp(desc->name, "activated") == 0)
evt_desc = ELM_FILESELECTOR_EVENT_ACTIVATED;
else if (strcmp(desc->name, "directory,open") == 0)
evt_desc = ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN;
else if (strcmp(desc->name, "done") == 0)
evt_desc = ELM_FILESELECTOR_EVENT_DONE;
else if (strcmp(desc->name, "selected,invalid") == 0)
evt_desc = ELM_FILESELECTOR_EVENT_SELECTED_INVALID;
else
return efl_event_callback_legacy_call(efl_super(obj, MY_CLASS), desc, event_info);
return _from_legacy_event_call(obj, sd, desc, evt_desc, event_info);
}
if (desc == EFL_UI_EVENT_SELECTED ||
desc == ELM_FILESELECTOR_EVENT_ACTIVATED ||
desc == ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN ||
desc == ELM_FILESELECTOR_EVENT_DONE ||
desc == ELM_FILESELECTOR_EVENT_SELECTED_INVALID)
{
return _from_efl_event_call(obj, desc, event_info);
}
return efl_event_callback_legacy_call(efl_super(obj, MY_CLASS), desc, event_info);
}
EAPI void
elm_fileselector_is_save_set(Evas_Object *obj,
Eina_Bool is_save)

View File

@ -74,6 +74,8 @@ _replace_path_then(void *data, void *value)
const char *path = NULL;
eina_value_get(value, &path);
eina_stringshare_replace(&sd->fsd.path, path);
_event_to_legacy_call
(sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, (void *)path);
}
static void
@ -82,6 +84,8 @@ _replace_path_then_error(void *data, Eina_Error err EINA_UNUSED)
Elm_Fileselector_Button_Data *sd = data;
ERR("could not get information from Efl.Model");
eina_stringshare_replace(&sd->fsd.path, NULL);
_event_to_legacy_call
(sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, NULL);
}
static void
@ -99,32 +103,19 @@ _selection_done(void *data, const Eo_Event *event)
sd->fsd.model = efl_ref(model);
promise = efl_model_property_get(model, "path");
eina_promise_then(promise, _replace_path_then, _replace_path_then_error, sd);
efl_event_callback_call
(sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, model);
}
else
{
_model_event_call
(sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, NULL, NULL);
}
del = sd->fsw;
sd->fs = NULL;
sd->fsw = NULL;
evas_object_del(del);
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, (void *)model);
}
static void
_selection_done_path(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Elm_Fileselector_Button_Data *sd = data;
const char *path = event_info;
evas_object_smart_callback_call(sd->obj, "file,chosen", (void *) path);
// EVENTS: code above should not be needed
Eo_Event e = { NULL, NULL, NULL };
if (path)
e.info = efl_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(efl_self, path));
_selection_done(data, &e);
}
static Evas_Object *
@ -189,10 +180,8 @@ _activate(Elm_Fileselector_Button_Data *sd)
evas_object_size_hint_weight_set
(sd->fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
// EVENTS: should not call legacy
//efl_event_callback_add
// (sd->fs, ELM_FILESELECTOR_EVENT_DONE, _selection_done, sd);
evas_object_smart_callback_add(sd->fs, "done", _selection_done_path, sd);
efl_event_callback_add
(sd->fs, ELM_FILESELECTOR_EVENT_DONE, _selection_done, sd);
evas_object_show(sd->fs);
if (is_inwin)

View File

@ -33,6 +33,7 @@ EAPI const char ELM_FILESELECTOR_ENTRY_SMART_NAME[] = "elm_fileselector_entry";
cmd(SIG_SELECTION_COPY, "selection,copy", "") \
cmd(SIG_SELECTION_CUT, "selection,cut", "") \
cmd(SIG_UNPRESSED, "unpressed", "") \
cmd(SIG_FILE_CHOSEN, "file,chosen", "s") \
ELM_PRIV_FILESELECTOR_ENTRY_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
@ -67,19 +68,32 @@ SIG_FWD(UNPRESSED, EFL_UI_EVENT_UNPRESSED)
static void
_file_chosen_path_then(void *data, void *v)
{
Eina_Array *args = data;
const char *file = NULL;
char *s;
Eo *fs = eina_array_data_get(args, 0);
Efl_Model *model = eina_array_data_get(args, 1);
eina_array_free(args);
eina_value_get(v, &file);
if (!file) return;
ELM_FILESELECTOR_ENTRY_DATA_GET(data, sd);
ELM_FILESELECTOR_ENTRY_DATA_GET(fs, sd);
s = elm_entry_utf8_to_markup(file);
elm_object_text_set(sd->entry, s);
free(s);
evas_object_smart_callback_call(data, "file,chosen", (void *) file);
_model_event_call
(fs, ELM_FILESELECTOR_ENTRY_EVENT_FILE_CHOSEN, model, file);
}
static void
_file_chosen_path_then_error(void *data, Eina_Error err)
{
ERR("Efl.Model property \"path\" error: %s", eina_error_msg_get(err));
eina_array_free(data);
}
static void
@ -87,27 +101,17 @@ _FILE_CHOSEN_fwd(void *data, const Eo_Event *event)
{
Efl_Model *model = event->info;
Eina_Promise *promise = NULL;
Eina_Array *args = NULL;
if (!model) return;
args = eina_array_new(2);
eina_array_push(args, data);
eina_array_push(args, model);
promise = efl_model_property_get(model, "path");
eina_promise_then(promise, _file_chosen_path_then, NULL, data);
// EVENTS: should not call legacy
//efl_event_callback_legacy_call
// (data, ELM_FILESELECTOR_ENTRY_EVENT_FILE_CHOSEN, event->info);
}
// EVENTS: should not need this function
static void
_FILE_CHOSEN_fwd_path(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
const char *path = event_info;
Eo_Event e = { NULL, NULL, NULL };
if (path)
e.info = efl_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(efl_self, path));
_FILE_CHOSEN_fwd(data, &e);
eina_promise_then
(promise, _file_chosen_path_then, _file_chosen_path_then_error, args);
}
static void
@ -328,11 +332,8 @@ _elm_fileselector_entry_efl_canvas_group_group_add(Eo *obj, Elm_Fileselector_Ent
efl_event_callback_add(priv->button, event, _##name##_fwd, obj)
SIG_FWD(CLICKED, EFL_UI_EVENT_CLICKED);
SIG_FWD(UNPRESSED, EFL_UI_EVENT_UNPRESSED);
// EVENTS: should not call legacy
//SIG_FWD(FILE_CHOSEN, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN);
SIG_FWD(FILE_CHOSEN, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN);
#undef SIG_FWD
// EVENTS: should not need this "callback_add"
evas_object_smart_callback_add(priv->button, "file,chosen", _FILE_CHOSEN_fwd_path, obj);
priv->entry = elm_entry_add(obj);
elm_entry_scrollable_set(priv->entry, EINA_TRUE);

View File

@ -34,6 +34,7 @@ class Elm.Fileselector (Elm.Layout, Elm.Interface.Fileselector,
class.constructor;
class.destructor;
Efl.Object.constructor;
Efl.Object.event_callback_legacy_call;
Efl.Canvas.Group.group_add;
Efl.Canvas.Group.group_del;
Elm.Widget.focus_next;

View File

@ -35,4 +35,10 @@ _elm_fileselector_button_path_set_internal(Evas_Object *obj, const char *path);
const char *
_elm_fileselector_button_path_get_internal(const Evas_Object *obj);
void
_event_to_legacy_call(Eo *obj, const Efl_Event_Description *evt_desc, void *event_info);
void
_model_event_call(Eo *obj, const Efl_Event_Description *evt_desc, Efl_Model *model, const char *path);
#endif