Efl.Ui.Popup.Anchor: apply group calculate with size problem fix

Summary:
Size and align calculation in Efl.Ui.Popup was advanced using group calculate,
so Efl.Ui.Popup.Anchor apply it also.

Test Plan: elementary_test -to efl.ui.popup.anchor

Reviewers: Jaehyun_Cho, herb, jpeg, woohyun, cedric

Reviewed By: Jaehyun_Cho

Differential Revision: https://phab.enlightenment.org/D5655
This commit is contained in:
JinYong Park 2017-12-15 13:56:25 +09:00 committed by Jaehyun Cho
parent fe8c5f8269
commit ccfa9ae220
5 changed files with 97 additions and 78 deletions

View File

@ -184,6 +184,22 @@ _position_set_cb(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
efl_gfx_position_set(p_data->efl_ui_popup, EINA_POSITION2D(0, 0));
}
static void
_popup_resize_cb(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
{
efl_ui_popup_data *p_data = data;
if (!p_data->efl_ui_popup) return;
static Eina_Bool size_changed = EINA_FALSE;
if (!size_changed)
efl_ui_popup_size_set(p_data->efl_ui_popup, EINA_SIZE2D(300, 160));
else
efl_ui_popup_size_set(p_data->efl_ui_popup, EINA_SIZE2D(160, 120));
size_changed = !size_changed;
}
static void
_timeout_set_cb(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
{
@ -1038,37 +1054,43 @@ test_ui_popup_anchor(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void
efl_text_set(btn, "Center Align");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(70, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _center_align_cb, p_data);
efl_pack_grid(grid, btn, 0, 0, 1, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Left Align");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(70, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _left_align_cb, p_data);
efl_pack_grid(grid, btn, 1, 0, 1, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Right Align");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(70, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _right_align_cb, p_data);
efl_pack_grid(grid, btn, 2, 0, 1, 1);
efl_pack_grid(grid, btn, 0, 0, 2, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Top Align");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(70, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _top_align_cb, p_data);
efl_pack_grid(grid, btn, 0, 1, 1, 1);
efl_pack_grid(grid, btn, 2, 0, 2, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Bottom Align");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(70, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _bottom_align_cb, p_data);
efl_pack_grid(grid, btn, 1, 1, 1, 1);
efl_pack_grid(grid, btn, 4, 0, 2, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Left Align");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(100, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _left_align_cb, p_data);
efl_pack_grid(grid, btn, 0, 1, 3, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Right Align");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(100, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _right_align_cb, p_data);
efl_pack_grid(grid, btn, 3, 1, 3, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Position Set");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(70, 35));
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(100, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _position_set_cb, p_data);
efl_pack_grid(grid, btn, 2, 1, 1, 1);
efl_pack_grid(grid, btn, 0, 2, 3, 1);
btn = efl_add(EFL_UI_BUTTON_CLASS, efl_ui_popup);
efl_text_set(btn, "Resize");
efl_gfx_size_hint_min_set(btn, EINA_SIZE2D(100, 35));
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _popup_resize_cb, p_data);
efl_pack_grid(grid, btn, 3, 2, 3, 1);
efl_content_set(efl_ui_popup, grid);
}

View File

@ -40,9 +40,6 @@ _calc_align(Eo *obj)
Eina_Rect p_geom = efl_gfx_geometry_get(pd->win_parent);
efl_gfx_position_set(pd->backwall, EINA_POSITION2D(0, 0));
efl_gfx_size_set(pd->backwall, EINA_SIZE2D(p_geom.w, p_geom.h));
Eina_Rect o_geom = efl_gfx_geometry_get(obj);
Evas_Coord pw, ph;
@ -80,10 +77,7 @@ _efl_ui_popup_efl_gfx_size_set(Eo *obj, Efl_Ui_Popup_Data *pd EINA_UNUSED, Eina_
{
efl_gfx_size_set(efl_super(obj, MY_CLASS), size);
//Add align calc only
Eina_Bool needs_size_calc = pd->needs_size_calc;
elm_layout_sizing_eval(obj);
pd->needs_size_calc = needs_size_calc;
}
static void
@ -312,6 +306,12 @@ _efl_ui_popup_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Popup_Data *pd)
_calc_align(obj);
pd->needs_align_calc = EINA_FALSE;
}
Eina_Rect p_geom = efl_gfx_geometry_get(pd->win_parent);
efl_gfx_position_set(pd->backwall, EINA_POSITION2D(0, 0));
efl_gfx_size_set(pd->backwall, EINA_SIZE2D(p_geom.w, p_geom.h));
pd->needs_group_calc = EINA_FALSE;
}
}

View File

@ -8,6 +8,7 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_popup_private.h"
#include "efl_ui_popup_anchor_private.h"
#define MY_CLASS EFL_UI_POPUP_ANCHOR_CLASS
@ -17,7 +18,8 @@ static void
_anchor_calc(Eo *obj)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd);
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
EFL_UI_POPUP_ANCHOR_DATA_GET(obj, pd);
Eina_Position2D pos = {0, 0};
@ -28,11 +30,11 @@ _anchor_calc(Eo *obj)
return;
}
Eina_Rect a_geom = efl_gfx_geometry_get(sd->anchor);
Eina_Rect a_geom = efl_gfx_geometry_get(pd->anchor);
Eina_Rect o_geom = efl_gfx_geometry_get(obj);
Eina_Rect p_geom = efl_gfx_geometry_get(parent);
sd->used_align = EFL_UI_POPUP_ALIGN_NONE;
pd->used_align = EFL_UI_POPUP_ALIGN_NONE;
/* 1. Find align which display popup.
It enables to shifting popup from exact position.
@ -46,9 +48,9 @@ _anchor_calc(Eo *obj)
Efl_Ui_Popup_Align cur_align;
if (idx == 0)
cur_align = sd->align;
cur_align = ppd->align;
else
cur_align = sd->priority[idx - 1];
cur_align = pd->priority[idx - 1];
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
continue;
@ -135,7 +137,7 @@ _anchor_calc(Eo *obj)
continue;
}
sd->used_align = cur_align;
pd->used_align = cur_align;
goto end;
}
@ -146,9 +148,9 @@ _anchor_calc(Eo *obj)
Efl_Ui_Popup_Align cur_align;
if (idx == 0)
cur_align = sd->align;
cur_align = ppd->align;
else
cur_align = sd->priority[idx - 1];
cur_align = pd->priority[idx - 1];
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
continue;
@ -158,35 +160,35 @@ _anchor_calc(Eo *obj)
case EFL_UI_POPUP_ALIGN_TOP:
pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
pos.y = (a_geom.y - o_geom.h);
sd->used_align = cur_align;
pd->used_align = cur_align;
goto end;
break;
case EFL_UI_POPUP_ALIGN_LEFT:
pos.x = (a_geom.x - o_geom.w);
pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
sd->used_align = cur_align;
pd->used_align = cur_align;
goto end;
break;
case EFL_UI_POPUP_ALIGN_RIGHT:
pos.x = (a_geom.x + a_geom.w);
pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
sd->used_align = cur_align;
pd->used_align = cur_align;
goto end;
break;
case EFL_UI_POPUP_ALIGN_BOTTOM:
pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
pos.y = (a_geom.y + a_geom.h);
sd->used_align = cur_align;
pd->used_align = cur_align;
goto end;
break;
case EFL_UI_POPUP_ALIGN_CENTER:
pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
sd->used_align = cur_align;
pd->used_align = cur_align;
goto end;
break;
@ -196,7 +198,7 @@ _anchor_calc(Eo *obj)
}
end:
if (sd->used_align != EFL_UI_POPUP_ALIGN_NONE)
if (pd->used_align != EFL_UI_POPUP_ALIGN_NONE)
efl_gfx_position_set(efl_super(obj, EFL_UI_POPUP_CLASS), pos);
}
@ -209,7 +211,8 @@ _anchor_geom_cb(void *data, const Efl_Event *ev EINA_UNUSED)
static void
_anchor_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
EFL_UI_POPUP_ANCHOR_DATA_GET(data, sd);
EFL_UI_POPUP_DATA_GET_OR_RETURN(data, ppd);
EFL_UI_POPUP_ANCHOR_DATA_GET(data, pd);
Eo *parent = efl_provider_find(data, EFL_UI_WIN_CLASS);
if (!parent)
@ -220,16 +223,19 @@ _anchor_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
efl_event_callback_del(parent, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, data);
sd->anchor = NULL;
efl_ui_popup_align_set(efl_super(data, MY_CLASS), sd->align);
pd->anchor = NULL;
//Add align calc only
Eina_Bool needs_size_calc = ppd->needs_size_calc;
elm_layout_sizing_eval(data);
ppd->needs_size_calc = needs_size_calc;
}
static void
_anchor_detach(Eo *obj)
{
EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd);
EFL_UI_POPUP_ANCHOR_DATA_GET(obj, pd);
if (sd->anchor == NULL) return;
if (!pd->anchor) return;
Eo *parent = efl_provider_find(obj, EFL_UI_WIN_CLASS);
if (!parent)
@ -239,25 +245,21 @@ _anchor_detach(Eo *obj)
}
efl_event_callback_del(parent, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
efl_event_callback_del(sd->anchor, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
efl_event_callback_del(sd->anchor, EFL_GFX_EVENT_MOVE, _anchor_geom_cb, obj);
efl_event_callback_del(sd->anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
efl_event_callback_del(pd->anchor, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_GFX_EVENT_MOVE, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
}
EOLIAN static void
_efl_ui_popup_anchor_anchor_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Eo *anchor)
{
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
_anchor_detach(obj);
pd->anchor = anchor;
if (anchor == NULL)
efl_ui_popup_align_set(efl_super(obj, MY_CLASS), pd->align);
else
if (anchor)
{
efl_ui_popup_align_set(efl_super(obj, MY_CLASS), EFL_UI_POPUP_ALIGN_NONE);
_anchor_calc(obj);
Eo *parent = efl_provider_find(obj, EFL_UI_WIN_CLASS);
if (!parent)
{
@ -270,6 +272,11 @@ _efl_ui_popup_anchor_anchor_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Eo *ancho
efl_event_callback_add(anchor, EFL_GFX_EVENT_MOVE, _anchor_geom_cb, obj);
efl_event_callback_add(anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
}
//Add align/anchor calc only
Eina_Bool needs_size_calc = ppd->needs_size_calc;
elm_layout_sizing_eval(obj);
ppd->needs_size_calc = needs_size_calc;
}
EOLIAN static Efl_Object *
@ -311,39 +318,33 @@ _efl_ui_popup_anchor_align_priority_get(Eo *obj EINA_UNUSED,
}
EOLIAN static void
_efl_ui_popup_anchor_efl_gfx_position_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED, Eina_Position2D pos)
_efl_ui_popup_anchor_efl_gfx_position_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Eina_Position2D pos)
{
_anchor_detach(obj);
pd->anchor = NULL;
pd->align = EFL_UI_POPUP_ALIGN_NONE;
efl_gfx_position_set(efl_super(obj, MY_CLASS), pos);
}
EOLIAN static void
_efl_ui_popup_anchor_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED)
_efl_ui_popup_anchor_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd)
{
elm_layout_sizing_eval(efl_super(obj, MY_CLASS));
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
/* When elm_layout_sizing_eval() is called, just flag is set instead of size
* calculation.
* The actual size calculation is done here when the object is rendered to
* avoid duplicate size calculations. */
if (ppd->needs_group_calc)
{
if (pd->anchor)
ppd->needs_align_calc = EINA_FALSE;
if (pd->anchor != NULL)
_anchor_calc(obj);
}
efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
EOLIAN static void
_efl_ui_popup_anchor_efl_ui_popup_align_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Efl_Ui_Popup_Align type)
{
pd->align = type;
if (pd->anchor == NULL)
efl_ui_popup_align_set(efl_super(obj, MY_CLASS), type);
else
_anchor_calc(obj);
}
EOLIAN static Efl_Ui_Popup_Align
_efl_ui_popup_anchor_efl_ui_popup_align_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Anchor_Data *pd)
{
return pd->align;
if (pd->anchor)
_anchor_calc(obj);
}
}
EOLIAN static Eo *
@ -368,7 +369,4 @@ _efl_ui_popup_anchor_efl_object_constructor(Eo *obj,
return obj;
}
#define EFL_UI_POPUP_ANCHOR_EXTRA_OPS \
ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_popup_anchor)
#include "efl_ui_popup_anchor.eo.c"

View File

@ -35,7 +35,7 @@ class Efl.Ui.Popup_Anchor(Efl.Ui.Popup)
}
implements {
Efl.Object.constructor;
Efl.Canvas.Group.group_calculate;
Efl.Gfx.position { set; }
Efl.Ui.Popup.align { set; get; }
}
}

View File

@ -7,7 +7,6 @@ typedef struct _Efl_Ui_Popup_Anchor_Data Efl_Ui_Popup_Anchor_Data;
struct _Efl_Ui_Popup_Anchor_Data
{
Eo *anchor;
Efl_Ui_Popup_Align align;
Efl_Ui_Popup_Align priority[5];
Efl_Ui_Popup_Align used_align;
};