efl_animation_view: on implementing part contents

This commit is contained in:
Hermet Park 2019-08-14 17:35:42 +09:00
parent 64e6e44776
commit 24a368abf5
1 changed files with 294 additions and 265 deletions

View File

@ -17,8 +17,8 @@
#define MY_CLASS_NAME "Efl_Ui_Animation_View"
#define MY_CLASS_NAME_LEGACY "efl_ui_animation_view"
#define T_SEGMENT_N 20
#define C_SEGMENT_N 20
#define T_SEGMENT_N 40
#define C_SEGMENT_N 40
#define DEFAULT_QUEUE_SIZE 300
static const char SIG_FOCUSED[] = "focused";
@ -49,6 +49,8 @@ typedef struct
{
Eina_Stringshare *part;
Eo *obj;
Eo *proxy;
const Efl_VG *node;
} Efl_Ui_Animation_View_Sub_Obj_Data;
typedef struct
@ -64,45 +66,58 @@ typedef struct
static Eo *proxy_obj[T_SEGMENT_N][T_SEGMENT_N];
Eina_Bool
_map_content(Efl_VG *node, const char *id, int off_x, int off_y, Eo* target)
Efl_VG *
_node_get(Efl_VG *node, const char *part)
{
if (!node) return EINA_FALSE;
if (!efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS)) return EINA_FALSE;
if (!node) return NULL;
if (!efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS)) return NULL;
char *name = efl_key_data_get(node, "_lot_node_name");
//Find the target recursively
if (!name || strcmp(name, id))
//Find the target recursiveldy
if (!name || strcmp(name, part))
{
Eina_Iterator *itr = efl_canvas_vg_container_children_get(node);
Efl_VG *child;
Efl_VG *ret;
EINA_ITERATOR_FOREACH(itr, child)
{
if (efl_isa(child, EFL_CANVAS_VG_CONTAINER_CLASS))
{
if (_map_content(child, id, off_x, off_y, target)) break;
ret = _node_get(child, part);
if (ret) return ret;
}
}
return EINA_FALSE;
return NULL;
}
//Find Shape
Eina_Iterator *itr = efl_canvas_vg_container_children_get(node);
Efl_VG *child;
const Efl_Gfx_Path_Command_Type *cmd;
EINA_ITERATOR_FOREACH(itr, child)
{
//Filter out unacceptable types
if (!efl_isa(child, EFL_CANVAS_VG_SHAPE_CLASS)) continue;
if (efl_gfx_shape_stroke_width_get(child) > 0) continue;
efl_gfx_path_get(child, &cmd, NULL);
if (!cmd) continue;
return child;
}
return NULL;
}
Eina_Bool
_part_draw(const Efl_VG *node, int off_x, int off_y, Eo* target)
{
const Efl_Gfx_Path_Command_Type *cmd;
const double *points;
efl_gfx_path_get(child, &cmd, NULL);
if (!cmd) continue;
efl_gfx_path_get(node, &cmd, NULL);
if (!cmd) return EINA_FALSE;
//Fast Path? Shape outlines by consisted of lines.
int pt_cnt = 0;
@ -127,13 +142,14 @@ _map_content(Efl_VG *node, const char *id, int off_x, int off_y, Eo* target)
fast_path = EINA_FALSE;
}
efl_gfx_path_get(child, &cmd, &points);
efl_gfx_path_get(node, &cmd, &points);
int rgba;
efl_gfx_color_get(child, NULL, NULL, NULL, &rgba);
int alpha;
efl_gfx_color_get(node, NULL, NULL, NULL, &alpha);
int pt_idx = 0;
double x, y;
Eina_Size2D tsize = efl_gfx_entity_size_get(target);
//Case 1. Rectangle Mapping
if (fast_path)
@ -146,16 +162,15 @@ _map_content(Efl_VG *node, const char *id, int off_x, int off_y, Eo* target)
x = points[pt_idx++] + off_x;
y = points[pt_idx++] + off_y;
evas_map_point_coord_set(map, map_idx, x, y, 0);
evas_map_point_color_set(map, map_idx++, rgba, rgba, rgba, rgba);
evas_map_point_color_set(map, map_idx++, alpha, alpha, alpha, alpha);
map_idx %= pt_cnt;
}
//Texture Coordinates
Eina_Rect geom = efl_gfx_entity_geometry_get(target);
evas_map_point_image_uv_set(map, 0, 0, 0);
evas_map_point_image_uv_set(map, 1, geom.w, 0);
evas_map_point_image_uv_set(map, 2, geom.w, geom.h);
evas_map_point_image_uv_set(map, 3, 0, geom.h);
evas_map_point_image_uv_set(map, 1, tsize.w, 0);
evas_map_point_image_uv_set(map, 2, tsize.w, tsize.h);
evas_map_point_image_uv_set(map, 3, 0, tsize.h);
evas_object_map_set(target, map);
evas_object_map_enable_set(target, EINA_TRUE);
@ -263,10 +278,9 @@ _map_content(Efl_VG *node, const char *id, int off_x, int off_y, Eo* target)
max_x = -1;
for (int j = 0; j < inarray_idx; ++j)
//EINA_INARRAY_FOREACH(inarray, pt)
{
pt = eina_inarray_nth(inarray, j);
pt2 = eina_inarray_nth(inarray, j + 1);
pt2 = pt + 1;
//Horizontal Line
if ((fabs(y - pt->y) < 0.5) &&
@ -313,11 +327,8 @@ _map_content(Efl_VG *node, const char *id, int off_x, int off_y, Eo* target)
}
Evas *evas = evas_object_evas_get(target);
int w, h;
evas_object_geometry_get(target, NULL, NULL, &w, &h);
float u_segment = ((float) w) / ((float) T_SEGMENT_N);
float v_segment = ((float) h) / ((float) T_SEGMENT_N);
float u_segment = ((float) tsize.w) / ((float) T_SEGMENT_N);
float v_segment = ((float) tsize.h) / ((float) T_SEGMENT_N);
for (int i = 0; i < T_SEGMENT_N; ++i)
{
@ -332,7 +343,7 @@ _map_content(Efl_VG *node, const char *id, int off_x, int off_y, Eo* target)
evas_object_image_source_set(proxy_obj[i][j], target);
evas_object_image_source_events_set(proxy_obj[i][j], EINA_TRUE);
evas_object_move(proxy_obj[i][j], -1000, -1000);
evas_object_resize(proxy_obj[i][j], w, h);
evas_object_resize(proxy_obj[i][j], tsize.w, tsize.h);
evas_object_show(proxy_obj[i][j]);
}
@ -348,35 +359,51 @@ _map_content(Efl_VG *node, const char *id, int off_x, int off_y, Eo* target)
evas_map_point_image_uv_set(map, 2, ((float) j + 1) * u_segment, ((float) i + 1) * v_segment);
evas_map_point_image_uv_set(map, 3, ((float) j) * u_segment, ((float) i + 1) * v_segment);
evas_map_point_color_set(map, 0, rgba, rgba, rgba, rgba);
evas_map_point_color_set(map, 1, rgba, rgba, rgba, rgba);
evas_map_point_color_set(map, 2, rgba, rgba, rgba, rgba);
evas_map_point_color_set(map, 3, rgba, rgba, rgba, rgba);
evas_map_point_color_set(map, 0, alpha, alpha, alpha, alpha);
evas_map_point_color_set(map, 1, alpha, alpha, alpha, alpha);
evas_map_point_color_set(map, 2, alpha, alpha, alpha, alpha);
evas_map_point_color_set(map, 3, alpha, alpha, alpha, alpha);
evas_object_map_enable_set(proxy_obj[i][j], EINA_TRUE);
evas_object_map_set(proxy_obj[i][j], map);
}
}
eina_inarray_free(inarray);
return EINA_TRUE;
}
return EINA_FALSE;
}
static void
_update_part_contents(Efl_Ui_Animation_View_Data *pd)
{
if (!pd->subs || !pd->vg) return;
if (!pd->subs) return;
//TODO: Update to current frame's node tree immediately.
Efl_VG *root = evas_object_vg_root_node_get(pd->vg);
if (!root) return;
Eina_Position2D pos = efl_gfx_entity_position_get(pd->vg);
Eina_List *l;
Eina_Position2D pos = efl_gfx_entity_position_get(pd->vg);
Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
EINA_LIST_FOREACH(pd->subs, l, sub_d)
_map_content(root, sub_d->part, pos.x, pos.y, sub_d->obj);
{
if (!sub_d->node)
sub_d->node = _node_get(root, sub_d->part);
if (sub_d->node)
_part_draw(sub_d->node, pos.x, pos.y, sub_d->obj);
}
}
static void
_frame_set_facade(Efl_Ui_Animation_View_Data *pd, int frame)
{
int pframe = evas_object_vg_animated_frame_get(pd->vg);
evas_object_vg_animated_frame_set(pd->vg, frame);
if (pframe != frame) _update_part_contents(pd);
}
static void
@ -395,6 +422,7 @@ _on_sub_object_size_hint_change(void *data,
if (!efl_alive_get(data)) return;
ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
efl_canvas_group_change(data);
//TODO: Update part contents
}
static void
@ -541,7 +569,7 @@ _transit_cb(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
int update_frame = (int)((maxframe - minframe) * progress) + minframe;
int current_frame = evas_object_vg_animated_frame_get(pd->vg);
evas_object_vg_animated_frame_set(pd->vg, update_frame);
_frame_set_facade(pd, update_frame);
if (pd->auto_repeat)
{
@ -556,10 +584,7 @@ _transit_cb(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
//transit_cb is always called with a progress value 0 ~ 1.
//SIG_PLAY_UPDATE callback is called only when there is a real change.
if (update_frame != current_frame)
{
_update_part_contents(pd);
evas_object_smart_callback_call(obj, SIG_PLAY_UPDATE, NULL);
}
}
EOLIAN static void
@ -635,7 +660,7 @@ _ready_play(Eo *obj, Efl_Ui_Animation_View_Data *pd)
pd->frame_cnt = (double) evas_object_vg_animated_frame_count_get(pd->vg);
pd->frame_duration = evas_object_vg_animated_frame_duration_get(pd->vg, 0, 0);
evas_object_vg_animated_frame_set(pd->vg, 0);
_frame_set_facade(pd, 0);
if (pd->frame_duration > 0)
{
@ -834,7 +859,8 @@ _efl_ui_animation_view_stop(Eo *obj, Efl_Ui_Animation_View_Data *pd)
(pd->state == EFL_UI_ANIMATION_VIEW_STATE_STOP))
return EINA_FALSE;
evas_object_vg_animated_frame_set(pd->vg, 0);
_frame_set_facade(pd, 0);
pd->progress = 0;
pd->state = EFL_UI_ANIMATION_VIEW_STATE_STOP;
evas_object_smart_callback_call(obj, SIG_PLAY_STOP, NULL);
@ -930,7 +956,7 @@ _efl_ui_animation_view_progress_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_D
pd->progress = progress;
if (pd->frame_cnt > 0)
evas_object_vg_animated_frame_set(pd->vg, (int) ((pd->frame_cnt - 1) * progress));
_frame_set_facade(pd, (int) ((pd->frame_cnt - 1) * progress));
if (pd->transit)
{
@ -1113,6 +1139,7 @@ _efl_ui_animation_view_efl_ui_widget_widget_sub_object_del(Eo *obj, Efl_Ui_Anima
{
if (sub_d->obj != sobj) continue;
pd->subs = eina_list_remove_list(pd->subs, l);
if (sub_d->proxy) efl_del(sub_d->proxy);
eina_stringshare_del(sub_d->part);
free(sub_d);
break;
@ -1191,6 +1218,8 @@ _efl_ui_animation_view_content_set(Eo *obj, Efl_Ui_Animation_View_Data *pd, cons
efl_canvas_group_change(obj);
_update_part_contents(pd);
end:
return EINA_TRUE;
}