forked from enlightenment/efl
efl_ui_popup_anchor: add Efl.Ui.Popup.Anchor class
Summary: Add initial code for Efl.Ui.Popup.Anchor class. It supports adding anchor object to popup. Test Plan: 1. run elementary_test -to efluipopupanchor Reviewers: Jaehyun_Cho, thiepha, herb, jpeg, cedric, woohyun Reviewed By: Jaehyun_Cho Differential Revision: https://phab.enlightenment.org/D5126
This commit is contained in:
parent
a7082df12b
commit
c8c7ac8aae
|
@ -933,4 +933,82 @@ collections {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
group { "efl_ui_popup_anchor_layout";
|
||||||
|
parts {
|
||||||
|
spacer { "base";
|
||||||
|
desc { "default";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swallow { "anchor1";
|
||||||
|
scale;
|
||||||
|
desc { "default";
|
||||||
|
rel.to: "base";
|
||||||
|
rel1.relative: 0.15 0.25;
|
||||||
|
rel2.relative: 0.15 0.25;
|
||||||
|
fixed: 1 1;
|
||||||
|
min: 50 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swallow { "anchor2";
|
||||||
|
scale;
|
||||||
|
desc { "default";
|
||||||
|
rel.to: "base";
|
||||||
|
rel1.relative: 0.75 0.15;
|
||||||
|
rel2.relative: 0.75 0.15;
|
||||||
|
fixed: 1 1;
|
||||||
|
min: 50 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swallow { "anchor3";
|
||||||
|
scale;
|
||||||
|
desc { "default";
|
||||||
|
rel.to: "base";
|
||||||
|
rel1.relative: 0.25 0.85;
|
||||||
|
rel2.relative: 0.25 0.85;
|
||||||
|
fixed: 1 1;
|
||||||
|
min: 50 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swallow { "anchor4";
|
||||||
|
scale;
|
||||||
|
desc { "default";
|
||||||
|
rel.to: "base";
|
||||||
|
rel1.relative: 0.85 0.75;
|
||||||
|
rel2.relative: 0.85 0.75;
|
||||||
|
fixed: 1 1;
|
||||||
|
min: 50 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swallow { "anchor5";
|
||||||
|
scale;
|
||||||
|
desc { "default";
|
||||||
|
rel.to: "base";
|
||||||
|
rel1.relative: 0.45 0.35;
|
||||||
|
rel2.relative: 0.45 0.35;
|
||||||
|
fixed: 1 1;
|
||||||
|
min: 50 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swallow { "anchor6";
|
||||||
|
scale;
|
||||||
|
desc { "default";
|
||||||
|
rel.to: "base";
|
||||||
|
rel2.relative: 0.0 0.0;
|
||||||
|
rel1.offset: 150 300;
|
||||||
|
rel2.offset: 200 350;
|
||||||
|
fixed: 1 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swallow { "anchor_none";
|
||||||
|
scale;
|
||||||
|
desc { "default";
|
||||||
|
rel.to: "base";
|
||||||
|
rel1.relative: 0.60 0.45;
|
||||||
|
rel2.relative: 0.60 0.45;
|
||||||
|
fixed: 1 1;
|
||||||
|
min: 70 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ elm_public_eolian_files = \
|
||||||
lib/elementary/efl_ui_popup_alert_scroll_part.eo \
|
lib/elementary/efl_ui_popup_alert_scroll_part.eo \
|
||||||
lib/elementary/efl_ui_popup_alert_text.eo \
|
lib/elementary/efl_ui_popup_alert_text.eo \
|
||||||
lib/elementary/efl_ui_popup_alert_text_part.eo \
|
lib/elementary/efl_ui_popup_alert_text_part.eo \
|
||||||
|
lib/elementary/efl_ui_popup_anchor.eo \
|
||||||
lib/elementary/efl_ui_text_editable.eo \
|
lib/elementary/efl_ui_text_editable.eo \
|
||||||
lib/elementary/efl_ui_text_async.eo \
|
lib/elementary/efl_ui_text_async.eo \
|
||||||
lib/elementary/efl_ui_textpath.eo \
|
lib/elementary/efl_ui_textpath.eo \
|
||||||
|
@ -295,6 +296,7 @@ includesunstable_HEADERS = \
|
||||||
lib/elementary/efl_ui_popup_alert_private.h \
|
lib/elementary/efl_ui_popup_alert_private.h \
|
||||||
lib/elementary/efl_ui_popup_alert_scroll_private.h \
|
lib/elementary/efl_ui_popup_alert_scroll_private.h \
|
||||||
lib/elementary/efl_ui_popup_alert_text_private.h \
|
lib/elementary/efl_ui_popup_alert_text_private.h \
|
||||||
|
lib/elementary/efl_ui_popup_anchor_private.h \
|
||||||
lib/elementary/elm_widget_index.h \
|
lib/elementary/elm_widget_index.h \
|
||||||
lib/elementary/elm_widget_inwin.h \
|
lib/elementary/elm_widget_inwin.h \
|
||||||
lib/elementary/elm_widget_label.h \
|
lib/elementary/elm_widget_label.h \
|
||||||
|
@ -708,6 +710,7 @@ lib_elementary_libelementary_la_SOURCES = \
|
||||||
lib/elementary/efl_ui_popup_alert.c \
|
lib/elementary/efl_ui_popup_alert.c \
|
||||||
lib/elementary/efl_ui_popup_alert_scroll.c \
|
lib/elementary/efl_ui_popup_alert_scroll.c \
|
||||||
lib/elementary/efl_ui_popup_alert_text.c \
|
lib/elementary/efl_ui_popup_alert_text.c \
|
||||||
|
lib/elementary/efl_ui_popup_anchor.c \
|
||||||
lib/elementary/efl_ui_grid.c \
|
lib/elementary/efl_ui_grid.c \
|
||||||
lib/elementary/efl_ui_grid_static.c \
|
lib/elementary/efl_ui_grid_static.c \
|
||||||
lib/elementary/efl_ui_grid_private.h \
|
lib/elementary/efl_ui_grid_private.h \
|
||||||
|
|
|
@ -278,6 +278,7 @@ void test_efl_ui_popup(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_efl_ui_popup_alert(void *data, Evas_Object *obj, void *event_info);
|
void test_efl_ui_popup_alert(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_efl_ui_popup_alert_scroll(void *data, Evas_Object *obj, void *event_info);
|
void test_efl_ui_popup_alert_scroll(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_efl_ui_popup_alert_text(void *data, Evas_Object *obj, void *event_info);
|
void test_efl_ui_popup_alert_text(void *data, Evas_Object *obj, void *event_info);
|
||||||
|
void test_efl_ui_popup_anchor(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_dayselector(void *data, Evas_Object *obj, void *event_info);
|
void test_dayselector(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_image(void *data, Evas_Object *obj, void *event_info);
|
void test_image(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_image_scale_type(void *data, Evas_Object *obj, void *event_info);
|
void test_image_scale_type(void *data, Evas_Object *obj, void *event_info);
|
||||||
|
@ -1050,6 +1051,7 @@ add_tests:
|
||||||
ADD_TEST(NULL, "Popups", "Efl UI Popup Alert", test_efl_ui_popup_alert);
|
ADD_TEST(NULL, "Popups", "Efl UI Popup Alert", test_efl_ui_popup_alert);
|
||||||
ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Scroll", test_efl_ui_popup_alert_scroll);
|
ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Scroll", test_efl_ui_popup_alert_scroll);
|
||||||
ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Text", test_efl_ui_popup_alert_text);
|
ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Text", test_efl_ui_popup_alert_text);
|
||||||
|
ADD_TEST(NULL, "Popups", "Efl UI Popup Anchor", test_efl_ui_popup_anchor);
|
||||||
|
|
||||||
//------------------------------//
|
//------------------------------//
|
||||||
ADD_TEST(NULL, "Times & Dates", "Calendar", test_calendar);
|
ADD_TEST(NULL, "Times & Dates", "Calendar", test_calendar);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "elementary_config.h"
|
# include "elementary_config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define EFL_UI_POPUP_ANCHOR_BETA
|
||||||
#include <Elementary.h>
|
#include <Elementary.h>
|
||||||
|
|
||||||
#define POPUP_POINT_MAX 8
|
#define POPUP_POINT_MAX 8
|
||||||
|
@ -1205,3 +1207,117 @@ test_efl_ui_popup_alert_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSE
|
||||||
|
|
||||||
efl_event_callback_add(efl_ui_popup, EFL_UI_POPUP_ALERT_EVENT_CLICKED, efl_ui_popup_alert_clicked_cb, NULL);
|
efl_event_callback_add(efl_ui_popup, EFL_UI_POPUP_ALERT_EVENT_CLICKED, efl_ui_popup_alert_clicked_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_anchor_set_cb(void *data, Evas_Object *obj EINA_UNUSED,
|
||||||
|
void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
efl_ui_popup_anchor_set(data, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_anchor_unset_cb(void *data, Evas_Object *obj EINA_UNUSED,
|
||||||
|
void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
efl_ui_popup_anchor_set(data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_efl_ui_popup_anchor(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Evas_Object *win, *layout, *tbl, *btn;
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
|
win = elm_win_util_standard_add("Efl UI AnchorPopup", "Efl UI AnchorPopup");
|
||||||
|
elm_win_autodel_set(win, EINA_TRUE);
|
||||||
|
|
||||||
|
evas_object_resize(win, 500, 500);
|
||||||
|
evas_object_show(win);
|
||||||
|
|
||||||
|
layout = elm_layout_add(win);
|
||||||
|
snprintf(buf, sizeof(buf), "%s/objects/test.edj", elm_app_data_dir_get());
|
||||||
|
elm_layout_file_set(layout, buf, "efl_ui_popup_anchor_layout");
|
||||||
|
evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
elm_win_resize_object_add(win, layout);
|
||||||
|
evas_object_show(layout);
|
||||||
|
|
||||||
|
Evas_Object *efl_ui_popup= efl_add(EFL_UI_POPUP_ANCHOR_CLASS, win);
|
||||||
|
|
||||||
|
efl_ui_popup_bg_repeat_events_set(efl_ui_popup, EINA_TRUE);
|
||||||
|
|
||||||
|
//Default align priority order is top, left, right, bottom, center.
|
||||||
|
efl_ui_popup_anchor_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,
|
||||||
|
EFL_UI_POPUP_ALIGN_CENTER);
|
||||||
|
|
||||||
|
evas_object_move(efl_ui_popup, 80, 80);
|
||||||
|
evas_object_resize(efl_ui_popup, 160, 120);
|
||||||
|
evas_object_show(efl_ui_popup);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
btn = elm_button_add(win);
|
||||||
|
elm_object_text_set(btn, "anchor");
|
||||||
|
evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _anchor_set_cb, efl_ui_popup);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "anchor%d", i+1);
|
||||||
|
elm_object_part_content_set(layout, buf, btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
btn = elm_button_add(win);
|
||||||
|
elm_object_text_set(btn, "anchor none");
|
||||||
|
evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _anchor_unset_cb, efl_ui_popup);
|
||||||
|
elm_object_part_content_set(layout, "anchor_none", btn);
|
||||||
|
|
||||||
|
tbl = elm_table_add(efl_ui_popup);
|
||||||
|
evas_object_size_hint_weight_set(tbl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(tbl, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
|
|
||||||
|
btn = elm_button_add(efl_ui_popup);
|
||||||
|
elm_object_text_set(btn, "Center Align");
|
||||||
|
evas_object_size_hint_min_set(btn, 70, 35);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _center_align_cb, efl_ui_popup);
|
||||||
|
elm_table_pack(tbl, btn, 0, 0, 1, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
btn = elm_button_add(efl_ui_popup);
|
||||||
|
elm_object_text_set(btn, "Left Align");
|
||||||
|
evas_object_size_hint_min_set(btn, 70, 35);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _left_align_cb, efl_ui_popup);
|
||||||
|
elm_table_pack(tbl, btn, 1, 0, 1, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
btn = elm_button_add(efl_ui_popup);
|
||||||
|
elm_object_text_set(btn, "Right Align");
|
||||||
|
evas_object_size_hint_min_set(btn, 70, 35);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _right_align_cb, efl_ui_popup);
|
||||||
|
elm_table_pack(tbl, btn, 2, 0, 1, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
btn = elm_button_add(efl_ui_popup);
|
||||||
|
elm_object_text_set(btn, "Top Align");
|
||||||
|
evas_object_size_hint_min_set(btn, 70, 35);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _top_align_cb, efl_ui_popup);
|
||||||
|
elm_table_pack(tbl, btn, 0, 1, 1, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
btn = elm_button_add(efl_ui_popup);
|
||||||
|
elm_object_text_set(btn, "Bottom Align");
|
||||||
|
evas_object_size_hint_min_set(btn, 70, 35);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _bottom_align_cb, efl_ui_popup);
|
||||||
|
elm_table_pack(tbl, btn, 1, 1, 1, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
btn = elm_button_add(efl_ui_popup);
|
||||||
|
elm_object_text_set(btn, "Position Set");
|
||||||
|
evas_object_size_hint_min_set(btn, 70, 35);
|
||||||
|
evas_object_smart_callback_add(btn, "clicked", _position_set_cb, efl_ui_popup);
|
||||||
|
elm_table_pack(tbl, btn, 2, 1, 1, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
efl_content_set(efl_ui_popup, tbl);
|
||||||
|
}
|
||||||
|
|
|
@ -305,6 +305,7 @@ EAPI extern Elm_Version *elm_version;
|
||||||
# include <efl_ui_popup_alert.eo.h>
|
# include <efl_ui_popup_alert.eo.h>
|
||||||
# include <efl_ui_popup_alert_scroll.eo.h>
|
# include <efl_ui_popup_alert_scroll.eo.h>
|
||||||
# include <efl_ui_popup_alert_text.eo.h>
|
# include <efl_ui_popup_alert_text.eo.h>
|
||||||
|
# include <efl_ui_popup_anchor.eo.h>
|
||||||
# include <efl_ui_text_editable.eo.h>
|
# include <efl_ui_text_editable.eo.h>
|
||||||
# include <efl_ui_text_async.eo.h>
|
# include <efl_ui_text_async.eo.h>
|
||||||
# include <efl_ui_clock.eo.h>
|
# include <efl_ui_clock.eo.h>
|
||||||
|
|
|
@ -0,0 +1,357 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "elementary_config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EFL_UI_POPUP_PROTECTED
|
||||||
|
#define EFL_UI_POPUP_ANCHOR_BETA
|
||||||
|
|
||||||
|
#include <Elementary.h>
|
||||||
|
|
||||||
|
#include "elm_priv.h"
|
||||||
|
#include "efl_ui_popup_anchor_private.h"
|
||||||
|
|
||||||
|
#define MY_CLASS EFL_UI_POPUP_ANCHOR_CLASS
|
||||||
|
#define MY_CLASS_NAME "Efl.Ui.Popup.Anchor"
|
||||||
|
|
||||||
|
static void
|
||||||
|
_anchor_calc(Evas_Object *obj)
|
||||||
|
{
|
||||||
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
||||||
|
EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd);
|
||||||
|
|
||||||
|
Evas_Coord_Rectangle anchor_geom = {0, 0, 0, 0};
|
||||||
|
Evas_Coord_Size popup_size = {0, 0};
|
||||||
|
Evas_Coord_Size parent_size = {0, 0};
|
||||||
|
Eina_Position2D pos = {0, 0};
|
||||||
|
|
||||||
|
Evas_Object *parent = efl_ui_popup_parent_window_get(obj);
|
||||||
|
|
||||||
|
evas_object_geometry_get(sd->anchor, &anchor_geom.x, &anchor_geom.y, &anchor_geom.w, &anchor_geom.h);
|
||||||
|
evas_object_geometry_get(obj, NULL, NULL, &popup_size.w, &popup_size.h);
|
||||||
|
evas_object_geometry_get(parent, NULL, NULL, &parent_size.w, &parent_size.h);
|
||||||
|
|
||||||
|
sd->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 = sd->align;
|
||||||
|
else
|
||||||
|
cur_align = sd->priority[idx - 1];
|
||||||
|
|
||||||
|
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch(cur_align)
|
||||||
|
{
|
||||||
|
case EFL_UI_POPUP_ALIGN_TOP:
|
||||||
|
pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
|
||||||
|
pos.y = (anchor_geom.y - popup_size.h);
|
||||||
|
|
||||||
|
if ((pos.y < 0) ||
|
||||||
|
((pos.y + popup_size.h) > parent_size.h) ||
|
||||||
|
(popup_size.w > parent_size.w))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_LEFT:
|
||||||
|
pos.x = (anchor_geom.x - popup_size.w);
|
||||||
|
pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
|
||||||
|
|
||||||
|
if ((pos.x < 0) ||
|
||||||
|
((pos.x + popup_size.w) > parent_size.w) ||
|
||||||
|
(popup_size.h > parent_size.h))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_RIGHT:
|
||||||
|
pos.x = (anchor_geom.x + anchor_geom.w);
|
||||||
|
pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
|
||||||
|
|
||||||
|
if ((pos.x < 0) ||
|
||||||
|
((pos.x + popup_size.w) > parent_size.w) ||
|
||||||
|
(popup_size.h > parent_size.h))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_BOTTOM:
|
||||||
|
pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
|
||||||
|
pos.y = (anchor_geom.y + anchor_geom.h);
|
||||||
|
|
||||||
|
if ((pos.y < 0) ||
|
||||||
|
((pos.y + popup_size.h) > parent_size.h) ||
|
||||||
|
(popup_size.w > parent_size.w))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_CENTER:
|
||||||
|
pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
|
||||||
|
pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
|
||||||
|
|
||||||
|
if (popup_size.w > parent_size.w || popup_size.h > parent_size.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 + popup_size.w) > parent_size.w)
|
||||||
|
pos.x = parent_size.w - popup_size.w;
|
||||||
|
|
||||||
|
if ((pos.x > (anchor_geom.x + anchor_geom.w)) ||
|
||||||
|
((pos.x + popup_size.w) < anchor_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 + popup_size.h) > parent_size.h)
|
||||||
|
pos.y = parent_size.h - popup_size.h;
|
||||||
|
|
||||||
|
if ((pos.y > (anchor_geom.y + anchor_geom.h)) ||
|
||||||
|
((pos.y + popup_size.h) < anchor_geom.y))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sd->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 = sd->align;
|
||||||
|
else
|
||||||
|
cur_align = sd->priority[idx - 1];
|
||||||
|
|
||||||
|
if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch(cur_align)
|
||||||
|
{
|
||||||
|
case EFL_UI_POPUP_ALIGN_TOP:
|
||||||
|
pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
|
||||||
|
pos.y = (anchor_geom.y - popup_size.h);
|
||||||
|
sd->used_align = cur_align;
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_LEFT:
|
||||||
|
pos.x = (anchor_geom.x - popup_size.w);
|
||||||
|
pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
|
||||||
|
sd->used_align = cur_align;
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_RIGHT:
|
||||||
|
pos.x = (anchor_geom.x + anchor_geom.w);
|
||||||
|
pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
|
||||||
|
sd->used_align = cur_align;
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_BOTTOM:
|
||||||
|
pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
|
||||||
|
pos.y = (anchor_geom.y + anchor_geom.h);
|
||||||
|
sd->used_align = cur_align;
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFL_UI_POPUP_ALIGN_CENTER:
|
||||||
|
pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
|
||||||
|
pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
|
||||||
|
sd->used_align = cur_align;
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (sd->used_align != EFL_UI_POPUP_ALIGN_NONE)
|
||||||
|
efl_gfx_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_ANCHOR_DATA_GET(data, sd);
|
||||||
|
|
||||||
|
efl_event_callback_del(efl_ui_popup_parent_window_get(data), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, data);
|
||||||
|
|
||||||
|
sd->anchor = NULL;
|
||||||
|
efl_ui_popup_align_set(efl_super(data, MY_CLASS), sd->align);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_anchor_detach(Evas_Object *obj)
|
||||||
|
{
|
||||||
|
EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd);
|
||||||
|
|
||||||
|
if (sd->anchor == NULL) return;
|
||||||
|
|
||||||
|
efl_event_callback_del(efl_ui_popup_parent_window_get(obj), 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_popup_anchor_anchor_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Evas_Object *anchor)
|
||||||
|
{
|
||||||
|
_anchor_detach(obj);
|
||||||
|
pd->anchor = anchor;
|
||||||
|
|
||||||
|
if (anchor == NULL)
|
||||||
|
efl_ui_popup_align_set(efl_super(obj, MY_CLASS), pd->align);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
efl_ui_popup_align_set(efl_super(obj, MY_CLASS), EFL_UI_POPUP_ALIGN_NONE);
|
||||||
|
|
||||||
|
_anchor_calc(obj);
|
||||||
|
|
||||||
|
efl_event_callback_add(efl_ui_popup_parent_window_get(obj), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
|
||||||
|
efl_event_callback_add(anchor, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Efl_Object *
|
||||||
|
_efl_ui_popup_anchor_anchor_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Anchor_Data *pd)
|
||||||
|
{
|
||||||
|
return pd->anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_popup_anchor_align_priority_set(Eo *obj EINA_UNUSED,
|
||||||
|
Efl_Ui_Popup_Anchor_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_anchor_align_priority_get(Eo *obj EINA_UNUSED,
|
||||||
|
Efl_Ui_Popup_Anchor_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_popup_anchor_efl_gfx_position_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED, 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)
|
||||||
|
{
|
||||||
|
elm_layout_sizing_eval(efl_super(obj, MY_CLASS));
|
||||||
|
|
||||||
|
if (pd->anchor != NULL)
|
||||||
|
_anchor_calc(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_popup_anchor_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
||||||
|
|
||||||
|
efl_canvas_group_add(efl_super(obj, MY_CLASS));
|
||||||
|
elm_widget_sub_object_parent_add(obj);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_popup_anchor_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
efl_canvas_group_del(efl_super(obj, MY_CLASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_popup_anchor_class_constructor(Efl_Class *klass)
|
||||||
|
{
|
||||||
|
evas_smart_legacy_type_register(MY_CLASS_NAME, klass);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EFL_UI_POPUP_ANCHOR_EXTRA_OPS \
|
||||||
|
EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_popup_anchor), \
|
||||||
|
ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_popup_anchor)
|
||||||
|
|
||||||
|
#include "efl_ui_popup_anchor.eo.c"
|
|
@ -0,0 +1,40 @@
|
||||||
|
class Efl.Ui.Popup.Anchor(Efl.Ui.Popup)
|
||||||
|
{
|
||||||
|
methods {
|
||||||
|
@property anchor {
|
||||||
|
set {
|
||||||
|
[[Set anchor popup follows the 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 NULL, the anchor popup stop to following 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;
|
||||||
|
second: Efl.Ui.Popup.Align;
|
||||||
|
third: Efl.Ui.Popup.Align;
|
||||||
|
fourth: Efl.Ui.Popup.Align;
|
||||||
|
fifth: Efl.Ui.Popup.Align;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
implements {
|
||||||
|
class.constructor;
|
||||||
|
Efl.Gfx.position { set; }
|
||||||
|
Efl.Ui.Popup.align { set; get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef EFL_UI_POPUP_ANCHOR_H
|
||||||
|
#define EFL_UI_POPUP_ANCHOR_H
|
||||||
|
|
||||||
|
#include "Elementary.h"
|
||||||
|
|
||||||
|
typedef struct _Efl_Ui_Popup_Anchor_Data Efl_Ui_Popup_Anchor_Data;
|
||||||
|
struct _Efl_Ui_Popup_Anchor_Data
|
||||||
|
{
|
||||||
|
Evas_Object *anchor;
|
||||||
|
Efl_Ui_Popup_Align align;
|
||||||
|
Efl_Ui_Popup_Align priority[5];
|
||||||
|
Efl_Ui_Popup_Align used_align;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EFL_UI_POPUP_ANCHOR_DATA_GET(o, sd) \
|
||||||
|
Efl_Ui_Popup_Anchor_Data * sd = efl_data_scope_get(o, EFL_UI_POPUP_ANCHOR_CLASS)
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue