efl_ui/popup: remove anchor_popup class

Summary:
all functionality is now merged into the base popup class. this greatly
simplifies the codebase and deduplicates a lot of code

ref T7902
Depends on D9651

Reviewers: cedric

Reviewed By: cedric

Subscribers: herb, cedric, #reviewers, #committers

Tags: #efl_widgets

Maniphest Tasks: T7902

Differential Revision: https://phab.enlightenment.org/D9652
This commit is contained in:
Mike Blumenkrantz 2019-08-21 10:41:57 -04:00
parent bb62f71fe2
commit bedb6df973
12 changed files with 341 additions and 435 deletions

View File

@ -121,15 +121,10 @@ group { "efl/alert_popup";
}
}
group { "efl/anchor_popup";
inherit: "efl/popup";
}
group { "efl/popup/backwall";
alias: "efl/alert_popup/backwall";
alias: "efl/scroll_alert_popup/backwall";
alias: "efl/text_alert_popup/backwall";
alias: "efl/anchor_popup/backwall";
parts {
rect { "base";
desc { "default";

View File

@ -2,7 +2,7 @@
# include "elementary_config.h"
#endif
#define EFL_UI_ANCHOR_POPUP_BETA
#define EFL_UI_POPUP_BETA
#define EFL_UI_SCROLL_ALERT_POPUP_BETA
#include <Efl_Ui.h>
#include <Elementary.h>
@ -992,13 +992,13 @@ test_ui_text_alert_popup(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, v
static void
_anchor_set_cb(void *data, const Efl_Event *ev)
{
efl_ui_anchor_popup_anchor_set(data, ev->object);
efl_ui_popup_anchor_set(data, ev->object);
}
static void
_anchor_unset_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
efl_ui_anchor_popup_anchor_set(data, NULL);
efl_ui_popup_anchor_set(data, NULL);
}
void
@ -1021,12 +1021,12 @@ test_ui_anchor_popup(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void
efl_gfx_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
efl_content_set(win, layout);
Eo *efl_ui_popup = efl_add(EFL_UI_ANCHOR_POPUP_CLASS, win);
Eo *efl_ui_popup = efl_add(EFL_UI_POPUP_CLASS, win);
efl_ui_popup_part_backwall_repeat_events_set(efl_part(efl_ui_popup, "backwall"), EINA_TRUE);
//Default align priority order is top, left, right, bottom, center.
efl_ui_anchor_popup_align_priority_set(efl_ui_popup, EFL_UI_POPUP_ALIGN_TOP,
efl_ui_popup_align_priority_set(efl_ui_popup, EFL_UI_POPUP_ALIGN_TOP,
EFL_UI_POPUP_ALIGN_BOTTOM,
EFL_UI_POPUP_ALIGN_LEFT,
EFL_UI_POPUP_ALIGN_RIGHT,

View File

@ -269,7 +269,6 @@ typedef Eo Efl_Ui_Spotlight_Indicator;
# include <efl_ui_alert_popup.eo.h>
# include <efl_ui_scroll_alert_popup.eo.h>
# include <efl_ui_text_alert_popup.eo.h>
# include <efl_ui_anchor_popup.eo.h>
# include <efl_ui_popup_part_backwall.eo.h>
# include <efl_ui_grid.eo.h>
# include <efl_ui_list.eo.h>

View File

@ -313,7 +313,6 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_alert_popup.eo.h>
# include <efl_ui_scroll_alert_popup.eo.h>
# include <efl_ui_text_alert_popup.eo.h>
# include <efl_ui_anchor_popup.eo.h>
# include <efl_ui_popup_part_backwall.eo.h>
# include <efl_ui_text_factory_images.eo.h>
# include <efl_ui_text_factory_emoticons.eo.h>

View File

@ -1,337 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#define EFL_UI_POPUP_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_popup_private.h"
#include "efl_ui_anchor_popup_private.h"
#define MY_CLASS EFL_UI_ANCHOR_POPUP_CLASS
#define MY_CLASS_NAME "Efl.Ui.Anchor_Popup"
static void
_anchor_calc(Eo *obj)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
EFL_UI_ANCHOR_POPUP_DATA_GET(obj, pd);
if (!pd->anchor) return;
Eina_Position2D pos = {0, 0};
Eina_Rect a_geom = efl_gfx_entity_geometry_get(pd->anchor);
Eina_Rect o_geom = efl_gfx_entity_geometry_get(obj);
Eina_Rect p_geom = efl_gfx_entity_geometry_get(ppd->win_parent);
pd->used_align = EFL_UI_POPUP_ALIGN_NONE;
/* 1. Find align which display popup.
It enables to shifting popup from exact position.
LEFT, RIGHT - shift only y position within anchor object's height
TOP, BOTTOM - shift only x position within anchor object's width
CENTER - shift both x, y position within anchor object's area
*/
for (int idx = 0; idx < 6; idx++)
{
Efl_Ui_Popup_Align cur_align;
if (idx == 0)
cur_align = ppd->align;
else
cur_align = pd->priority[idx - 1];
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
continue;
switch(cur_align)
{
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);
if ((pos.y < 0) ||
((pos.y + o_geom.h) > p_geom.h) ||
(o_geom.w > p_geom.w))
continue;
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);
if ((pos.x < 0) ||
((pos.x + o_geom.w) > p_geom.w) ||
(o_geom.h > p_geom.h))
continue;
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);
if ((pos.x < 0) ||
((pos.x + o_geom.w) > p_geom.w) ||
(o_geom.h > p_geom.h))
continue;
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);
if ((pos.y < 0) ||
((pos.y + o_geom.h) > p_geom.h) ||
(o_geom.w > p_geom.w))
continue;
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);
if ((o_geom.w > p_geom.w) || (o_geom.h > p_geom.h))
continue;
break;
default:
continue;
}
if ((cur_align == EFL_UI_POPUP_ALIGN_TOP) ||
(cur_align == EFL_UI_POPUP_ALIGN_BOTTOM) ||
(cur_align == EFL_UI_POPUP_ALIGN_CENTER))
{
if (pos.x < 0)
pos.x = 0;
if ((pos.x + o_geom.w) > p_geom.w)
pos.x = p_geom.w - o_geom.w;
if ((pos.x > (a_geom.x + a_geom.w)) ||
((pos.x + o_geom.w) < a_geom.x))
continue;
}
if ((cur_align == EFL_UI_POPUP_ALIGN_LEFT) ||
(cur_align == EFL_UI_POPUP_ALIGN_RIGHT) ||
(cur_align == EFL_UI_POPUP_ALIGN_CENTER))
{
if (pos.y < 0)
pos.y = 0;
if ((pos.y + o_geom.h) > p_geom.h)
pos.y = p_geom.h - o_geom.h;
if ((pos.y > (a_geom.y + a_geom.h)) ||
((pos.y + o_geom.h) < a_geom.y))
continue;
}
pd->used_align = cur_align;
goto end;
}
/* 2. Move popup to fit first valid align although entire popup can't display */
for (int idx = 0; idx < 6; idx++)
{
Efl_Ui_Popup_Align cur_align;
if (idx == 0)
cur_align = ppd->align;
else
cur_align = pd->priority[idx - 1];
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
continue;
switch(cur_align)
{
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);
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);
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);
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);
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);
pd->used_align = cur_align;
goto end;
break;
default:
break;
}
}
end:
if (pd->used_align != EFL_UI_POPUP_ALIGN_NONE)
efl_gfx_entity_position_set(efl_super(obj, EFL_UI_POPUP_CLASS), pos);
}
static void
_anchor_geom_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
_anchor_calc(data);
}
static void
_anchor_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
EFL_UI_POPUP_DATA_GET_OR_RETURN(data, ppd);
EFL_UI_ANCHOR_POPUP_DATA_GET(data, pd);
efl_event_callback_del(ppd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, data);
pd->anchor = NULL;
_anchor_calc(data);
}
static void
_anchor_detach(Eo *obj)
{
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
EFL_UI_ANCHOR_POPUP_DATA_GET(obj, pd);
if (!pd->anchor) return;
efl_event_callback_del(ppd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
}
EOLIAN static void
_efl_ui_anchor_popup_anchor_set(Eo *obj, Efl_Ui_Anchor_Popup_Data *pd, Eo *anchor)
{
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
_anchor_detach(obj);
pd->anchor = anchor;
if (anchor)
{
efl_event_callback_add(ppd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_add(anchor, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_add(anchor, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_add(anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
}
_anchor_calc(obj);
}
EOLIAN static Efl_Object *
_efl_ui_anchor_popup_anchor_get(const Eo *obj EINA_UNUSED, Efl_Ui_Anchor_Popup_Data *pd)
{
return pd->anchor;
}
EOLIAN static void
_efl_ui_anchor_popup_align_priority_set(Eo *obj EINA_UNUSED,
Efl_Ui_Anchor_Popup_Data *pd,
Efl_Ui_Popup_Align first,
Efl_Ui_Popup_Align second,
Efl_Ui_Popup_Align third,
Efl_Ui_Popup_Align fourth,
Efl_Ui_Popup_Align fifth)
{
pd->priority[0] = first;
pd->priority[1] = second;
pd->priority[2] = third;
pd->priority[3] = fourth;
pd->priority[4] = fifth;
}
EOLIAN static void
_efl_ui_anchor_popup_align_priority_get(const Eo *obj EINA_UNUSED,
Efl_Ui_Anchor_Popup_Data *pd,
Efl_Ui_Popup_Align *first,
Efl_Ui_Popup_Align *second,
Efl_Ui_Popup_Align *third,
Efl_Ui_Popup_Align *fourth,
Efl_Ui_Popup_Align *fifth)
{
if (first) *first = pd->priority[0];
if (second) *second = pd->priority[1];
if (third) *third = pd->priority[2];
if (fourth) *fourth = pd->priority[3];
if (fifth) *fifth = pd->priority[4];
}
EOLIAN static void
_efl_ui_anchor_popup_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Anchor_Popup_Data *pd, Eina_Position2D pos)
{
_anchor_detach(obj);
pd->anchor = NULL;
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
}
EOLIAN static void
_efl_ui_anchor_popup_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Anchor_Popup_Data *pd EINA_UNUSED)
{
efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
_anchor_calc(obj);
}
EOLIAN static Eo *
_efl_ui_anchor_popup_efl_object_constructor(Eo *obj,
Efl_Ui_Anchor_Popup_Data *pd)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
if (!elm_widget_theme_klass_get(obj))
elm_widget_theme_klass_set(obj, "anchor_popup");
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
pd->priority[0] = EFL_UI_POPUP_ALIGN_TOP;
pd->priority[1] = EFL_UI_POPUP_ALIGN_LEFT;
pd->priority[2] = EFL_UI_POPUP_ALIGN_RIGHT;
pd->priority[3] = EFL_UI_POPUP_ALIGN_BOTTOM;
pd->priority[4] = EFL_UI_POPUP_ALIGN_CENTER;
return obj;
}
EOLIAN static void
_efl_ui_anchor_popup_efl_object_destructor(Eo *obj,
Efl_Ui_Anchor_Popup_Data *pd EINA_UNUSED)
{
_anchor_detach(obj);
efl_destructor(efl_super(obj, MY_CLASS));
}
#include "efl_ui_anchor_popup.eo.c"

View File

@ -1,42 +0,0 @@
class @beta Efl.Ui.Anchor_Popup extends Efl.Ui.Popup
{
[[EFL UI Anchor Popup class]]
methods {
@property anchor {
set {
[[Set anchor popup to follow an anchor object.
If anchor object is moved or parent window is resized, the anchor popup moves to the new position.
If anchor object is set to NULL, the anchor popup stops following the anchor object.
When the popup is moved by using gfx_position_set, anchor is set NULL.
]]
}
get {
[[Returns the anchor object which the popup is following.]]
}
values {
anchor: Efl.Canvas.Object; [[The object which popup is following.]]
}
}
@property align_priority @beta {
set {
[[Set the align priority of a popup.]]
}
get {
[[Get the align priority of a popup.]]
}
values {
first: Efl.Ui.Popup_Align; [[First align priority]]
second: Efl.Ui.Popup_Align; [[Second align priority]]
third: Efl.Ui.Popup_Align; [[Third align priority]]
fourth: Efl.Ui.Popup_Align; [[Fourth align priority]]
fifth: Efl.Ui.Popup_Align; [[Fifth align priority]]
}
}
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Canvas.Group.group_calculate;
Efl.Gfx.Entity.position { set; }
}
}

View File

@ -1,17 +0,0 @@
#ifndef EFL_UI_ANCHOR_POPUP_H
#define EFL_UI_ANCHOR_POPUP_H
#include "Elementary.h"
typedef struct _Efl_Ui_Anchor_Popup_Data Efl_Ui_Anchor_Popup_Data;
struct _Efl_Ui_Anchor_Popup_Data
{
Eo *anchor;
Efl_Ui_Popup_Align priority[5];
Efl_Ui_Popup_Align used_align;
};
#define EFL_UI_ANCHOR_POPUP_DATA_GET(o, sd) \
Efl_Ui_Anchor_Popup_Data * sd = efl_data_scope_get(o, EFL_UI_ANCHOR_POPUP_CLASS)
#endif

View File

@ -18,23 +18,6 @@
static const char PART_NAME_BACKWALL[] = "backwall";
static void
_backwall_clicked_cb(void *data,
Eo *o EINA_UNUSED,
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
Eo *obj = data;
efl_event_callback_call(obj, EFL_UI_POPUP_EVENT_BACKWALL_CLICKED, NULL);
}
EOLIAN static void
_efl_ui_popup_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Popup_Data *pd EINA_UNUSED, Eina_Position2D pos)
{
pd->align = EFL_UI_POPUP_ALIGN_NONE;
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
}
static void
_calc_align(Eo *obj)
{
@ -74,6 +57,293 @@ _calc_align(Eo *obj)
}
}
static void
_anchor_calc(Eo *obj)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, pd);
if (!pd->anchor) return;
Eina_Position2D pos = {0, 0};
Eina_Rect a_geom = efl_gfx_entity_geometry_get(pd->anchor);
Eina_Rect o_geom = efl_gfx_entity_geometry_get(obj);
Eina_Rect p_geom = efl_gfx_entity_geometry_get(pd->win_parent);
pd->used_align = EFL_UI_POPUP_ALIGN_NONE;
/* 1. Find align which display popup.
It enables to shifting popup from exact position.
LEFT, RIGHT - shift only y position within anchor object's height
TOP, BOTTOM - shift only x position within anchor object's width
CENTER - shift both x, y position within anchor object's area
*/
for (int idx = 0; idx < 6; idx++)
{
Efl_Ui_Popup_Align cur_align;
if (idx == 0)
cur_align = pd->align;
else
cur_align = pd->priority[idx - 1];
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
continue;
switch(cur_align)
{
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);
if ((pos.y < 0) ||
((pos.y + o_geom.h) > p_geom.h) ||
(o_geom.w > p_geom.w))
continue;
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);
if ((pos.x < 0) ||
((pos.x + o_geom.w) > p_geom.w) ||
(o_geom.h > p_geom.h))
continue;
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);
if ((pos.x < 0) ||
((pos.x + o_geom.w) > p_geom.w) ||
(o_geom.h > p_geom.h))
continue;
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);
if ((pos.y < 0) ||
((pos.y + o_geom.h) > p_geom.h) ||
(o_geom.w > p_geom.w))
continue;
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);
if ((o_geom.w > p_geom.w) || (o_geom.h > p_geom.h))
continue;
break;
default:
continue;
}
if ((cur_align == EFL_UI_POPUP_ALIGN_TOP) ||
(cur_align == EFL_UI_POPUP_ALIGN_BOTTOM) ||
(cur_align == EFL_UI_POPUP_ALIGN_CENTER))
{
if (pos.x < 0)
pos.x = 0;
if ((pos.x + o_geom.w) > p_geom.w)
pos.x = p_geom.w - o_geom.w;
if ((pos.x > (a_geom.x + a_geom.w)) ||
((pos.x + o_geom.w) < a_geom.x))
continue;
}
if ((cur_align == EFL_UI_POPUP_ALIGN_LEFT) ||
(cur_align == EFL_UI_POPUP_ALIGN_RIGHT) ||
(cur_align == EFL_UI_POPUP_ALIGN_CENTER))
{
if (pos.y < 0)
pos.y = 0;
if ((pos.y + o_geom.h) > p_geom.h)
pos.y = p_geom.h - o_geom.h;
if ((pos.y > (a_geom.y + a_geom.h)) ||
((pos.y + o_geom.h) < a_geom.y))
continue;
}
pd->used_align = cur_align;
goto end;
}
/* 2. Move popup to fit first valid align although entire popup can't display */
for (int idx = 0; idx < 6; idx++)
{
Efl_Ui_Popup_Align cur_align;
if (idx == 0)
cur_align = pd->align;
else
cur_align = pd->priority[idx - 1];
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
continue;
switch(cur_align)
{
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);
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);
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);
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);
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);
pd->used_align = cur_align;
goto end;
break;
default:
break;
}
}
end:
if (pd->used_align != EFL_UI_POPUP_ALIGN_NONE)
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
}
static void
_anchor_geom_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
_anchor_calc(data);
}
static void
_anchor_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
EFL_UI_POPUP_DATA_GET_OR_RETURN(data, pd);
efl_event_callback_del(pd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, data);
pd->anchor = NULL;
_anchor_calc(data);
}
static void
_anchor_detach(Eo *obj, Efl_Ui_Popup_Data *pd)
{
if (!pd->anchor) return;
efl_event_callback_del(pd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_del(pd->anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
}
EOLIAN static void
_efl_ui_popup_anchor_set(Eo *obj, Efl_Ui_Popup_Data *pd, Eo *anchor)
{
_anchor_detach(obj, pd);
pd->anchor = anchor;
if (anchor)
{
efl_event_callback_add(pd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_add(anchor, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_add(anchor, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _anchor_geom_cb, obj);
efl_event_callback_add(anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
_anchor_calc(obj);
}
else
_calc_align(obj);
}
EOLIAN static Efl_Object *
_efl_ui_popup_anchor_get(const Eo *obj EINA_UNUSED, Efl_Ui_Popup_Data *pd)
{
return pd->anchor;
}
EOLIAN static void
_efl_ui_popup_align_priority_set(Eo *obj EINA_UNUSED,
Efl_Ui_Popup_Data *pd,
Efl_Ui_Popup_Align first,
Efl_Ui_Popup_Align second,
Efl_Ui_Popup_Align third,
Efl_Ui_Popup_Align fourth,
Efl_Ui_Popup_Align fifth)
{
pd->priority[0] = first;
pd->priority[1] = second;
pd->priority[2] = third;
pd->priority[3] = fourth;
pd->priority[4] = fifth;
}
EOLIAN static void
_efl_ui_popup_align_priority_get(const Eo *obj EINA_UNUSED,
Efl_Ui_Popup_Data *pd,
Efl_Ui_Popup_Align *first,
Efl_Ui_Popup_Align *second,
Efl_Ui_Popup_Align *third,
Efl_Ui_Popup_Align *fourth,
Efl_Ui_Popup_Align *fifth)
{
if (first) *first = pd->priority[0];
if (second) *second = pd->priority[1];
if (third) *third = pd->priority[2];
if (fourth) *fourth = pd->priority[3];
if (fifth) *fifth = pd->priority[4];
}
static void
_backwall_clicked_cb(void *data,
Eo *o EINA_UNUSED,
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
Eo *obj = data;
efl_event_callback_call(obj, EFL_UI_POPUP_EVENT_BACKWALL_CLICKED, NULL);
}
EOLIAN static void
_efl_ui_popup_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Popup_Data *pd, Eina_Position2D pos)
{
pd->align = EFL_UI_POPUP_ALIGN_NONE;
_anchor_detach(obj, pd);
pd->anchor = NULL;
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
}
EOLIAN static void
_efl_ui_popup_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Popup_Data *pd, Eina_Size2D size)
{
@ -103,7 +373,7 @@ _hints_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
}
EOLIAN static void
_efl_ui_popup_efl_ui_widget_widget_parent_set(Eo *obj, Efl_Ui_Popup_Data *pd EINA_UNUSED, Eo *parent)
_efl_ui_popup_efl_ui_widget_widget_parent_set(Eo *obj, Efl_Ui_Popup_Data *pd, Eo *parent)
{
if (!parent)
{
@ -237,6 +507,11 @@ _efl_ui_popup_efl_object_constructor(Eo *obj, Efl_Ui_Popup_Data *pd)
pd->align = EFL_UI_POPUP_ALIGN_CENTER;
pd->priority[0] = EFL_UI_POPUP_ALIGN_TOP;
pd->priority[1] = EFL_UI_POPUP_ALIGN_LEFT;
pd->priority[2] = EFL_UI_POPUP_ALIGN_RIGHT;
pd->priority[3] = EFL_UI_POPUP_ALIGN_BOTTOM;
pd->priority[4] = EFL_UI_POPUP_ALIGN_CENTER;
return obj;
}
@ -244,6 +519,7 @@ EOLIAN static void
_efl_ui_popup_efl_object_destructor(Eo *obj, Efl_Ui_Popup_Data *pd)
{
ELM_SAFE_DEL(pd->backwall);
_anchor_detach(obj, pd);
efl_event_callback_del(pd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _parent_geom_cb,
obj);
@ -284,7 +560,10 @@ _efl_ui_popup_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Popup_Data *pd)
_sizing_eval(obj);
pd->in_calc = EINA_FALSE;
}
_calc_align(obj);
if (pd->anchor)
_anchor_calc(obj);
else
_calc_align(obj);
Eina_Rect p_geom = efl_gfx_entity_geometry_get(pd->win_parent);

View File

@ -36,6 +36,36 @@ class @beta Efl.Ui.Popup extends Efl.Ui.Layout_Base implements Efl.Content, Efl.
time: double; [[Timeout in seconds]]
}
}
@property anchor {
set {
[[Set anchor popup to follow an anchor object.
If anchor object is moved or parent window is resized, the anchor popup moves to the new position.
If anchor object is set to NULL, the anchor popup stops following the anchor object.
When the popup is moved by using gfx_position_set, anchor is set NULL.
]]
}
get {
[[Returns the anchor object which the popup is following.]]
}
values {
anchor: Efl.Canvas.Object; [[The object which popup is following.]]
}
}
@property align_priority {
set {
[[Set the align priority of a popup.]]
}
get {
[[Get the align priority of a popup.]]
}
values {
first: Efl.Ui.Popup_Align; [[First align priority]]
second: Efl.Ui.Popup_Align; [[Second align priority]]
third: Efl.Ui.Popup_Align; [[Third align priority]]
fourth: Efl.Ui.Popup_Align; [[Fourth align priority]]
fifth: Efl.Ui.Popup_Align; [[Fifth align priority]]
}
}
}
parts {
backwall: Efl.Ui.Popup_Part_Backwall; [[A backwall behind the popup.]]

View File

@ -7,6 +7,9 @@ struct _Efl_Ui_Popup_Data
Eo *win_parent;
Eo *backwall;
Efl_Ui_Popup_Align align;
Eo *anchor;
Efl_Ui_Popup_Align priority[5];
Efl_Ui_Popup_Align used_align;
Ecore_Timer *timer;
double timeout;
Eina_Bool in_calc : 1;

View File

@ -87,7 +87,6 @@ pub_eo_files = [
'efl_ui_scroll_alert_popup_part.eo',
'efl_ui_text_alert_popup.eo',
'efl_ui_text_alert_popup_part.eo',
'efl_ui_anchor_popup.eo',
'efl_ui_text_editable.eo',
'efl_ui_text_async.eo',
'efl_ui_text_factory_images.eo',
@ -312,7 +311,6 @@ elementary_headers_unstable = [
'efl_ui_alert_popup_private.h',
'efl_ui_scroll_alert_popup_private.h',
'efl_ui_text_alert_popup_private.h',
'efl_ui_anchor_popup_private.h',
'elm_widget_index.h',
'elm_widget_inwin.h',
'elm_widget_label.h',
@ -873,7 +871,6 @@ elementary_src = [
'efl_ui_alert_popup.c',
'efl_ui_scroll_alert_popup.c',
'efl_ui_text_alert_popup.c',
'efl_ui_anchor_popup.c',
'efl_ui_table.c',
'efl_ui_table_static.c',
'efl_ui_table_layout.c',

View File

@ -630,7 +630,7 @@ can_move_y(Align align)
static void
verify_anchor(Eo *popup, Eo **align_buttons, Align align, Eina_Size2D *popup_sz)
{
Eo *anchor = efl_ui_anchor_popup_anchor_get(popup);
Eo *anchor = efl_ui_popup_anchor_get(popup);
Eo *win = efl_provider_find(popup, EFL_UI_WIN_CLASS);
Eina_Rect anchor_geom;
Efl_Ui_Popup_Align cur_prio;
@ -766,10 +766,10 @@ EFL_START_TEST(efl_ui_test_popup_text_anchor)
ck_assert(efl_file_simple_load(layout, buf, "efl_ui_popup_anchor_layout"));
efl_content_set(win, layout);
popup = efl_add(EFL_UI_ANCHOR_POPUP_CLASS, win);
popup = efl_add(EFL_UI_POPUP_CLASS, win);
efl_ui_popup_part_backwall_repeat_events_set(efl_part(popup, "backwall"), EINA_TRUE);
//Default align priority order is top, left, right, bottom, center.
efl_ui_anchor_popup_align_priority_set(popup, EFL_UI_POPUP_ALIGN_TOP,
efl_ui_popup_align_priority_set(popup, EFL_UI_POPUP_ALIGN_TOP,
EFL_UI_POPUP_ALIGN_BOTTOM,
EFL_UI_POPUP_ALIGN_LEFT,
EFL_UI_POPUP_ALIGN_RIGHT,
@ -871,9 +871,9 @@ EFL_START_TEST(efl_ui_test_popup_text_anchor)
}
for (i = -1; i < num_anchors; i++)
{
if (i >= 0) efl_ui_anchor_popup_anchor_set(popup, bganchors[i]);
if (i >= 0) efl_ui_popup_anchor_set(popup, bganchors[i]);
/* -1 is anchored to win object */
else efl_ui_anchor_popup_anchor_set(popup, NULL);
else efl_ui_popup_anchor_set(popup, NULL);
for (unsigned int j = 0; j < ALIGN_RESIZE; j++)
{
verify_anchor(popup, aligns, j, &popup_sz);