forked from enlightenment/efl
efl_ui_relative_layout: introduce new relative container
Summary: Efl.Ui.Relative_Layout is a container which allows you to position and size with relation to each other. it is possible to position and size using relation like edje even though you don't know a edc script. Position and size can be changed dynamically using widget APIs. @feature ref T5487 Test Plan: make check examples elementary_test -to 'efl.ui.relative_layout' Reviewers: cedric, Hermet, Jaehyun_Cho, zmike, bu5hm4n, jpeg, segfaultxavi Reviewed By: Jaehyun_Cho, segfaultxavi Subscribers: segfaultxavi, kimcinoo Tags: #efl Maniphest Tasks: T5487 Differential Revision: https://phab.enlightenment.org/D7524
This commit is contained in:
parent
6716feb108
commit
3118bfc34b
|
@ -133,6 +133,7 @@ elm_public_eolian_files = \
|
|||
lib/elementary/efl_ui_text_part.eo \
|
||||
lib/elementary/efl_ui_caching_factory.eo \
|
||||
lib/elementary/efl_ui_widget_factory.eo \
|
||||
lib/elementary/efl_ui_relative_layout.eo \
|
||||
$(NULL)
|
||||
|
||||
# More public files -- FIXME
|
||||
|
@ -455,7 +456,8 @@ includesunstable_HEADERS = \
|
|||
lib/elementary/efl_page_indicator_icon.h \
|
||||
lib/elementary/efl_ui_tab_pager_private.h \
|
||||
lib/elementary/efl_ui_tab_bar_private.h \
|
||||
lib/elementary/efl_ui_tab_page_private.h
|
||||
lib/elementary/efl_ui_tab_page_private.h \
|
||||
lib/elementary/efl_ui_relative_layout_private.h
|
||||
includesunstabledir = $(includedir)/elementary-@VMAJ@
|
||||
|
||||
nodist_includesunstable_HEADERS = \
|
||||
|
@ -893,6 +895,7 @@ lib_elementary_libelementary_la_SOURCES = \
|
|||
lib/elementary/efl_ui_homogeneous_model.c \
|
||||
lib/elementary/efl_ui_exact_model.c \
|
||||
lib/elementary/efl_ui_average_model.c \
|
||||
lib/elementary/efl_ui_relative_layout.c \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -1111,6 +1114,7 @@ bin/elementary/test_gesture_framework.c \
|
|||
bin/elementary/test_ui_tab_pager.c \
|
||||
bin/elementary/test_ui_pager.c \
|
||||
bin/elementary/test_ui_pager_scroll.c \
|
||||
bin/elementary/test_ui_relative_layout.c \
|
||||
bin/elementary/test.h
|
||||
|
||||
bin_elementary_elementary_test_LDADD = @USE_ELEMENTARY_LIBS@
|
||||
|
@ -1620,6 +1624,7 @@ tests_elementary_efl_ui_suite_SOURCES = \
|
|||
tests/elementary/efl_ui_test_focus.c \
|
||||
tests/elementary/efl_ui_test_focus_sub.c \
|
||||
tests/elementary/efl_ui_test_box.c \
|
||||
tests/elementary/efl_ui_test_relative_layout.c \
|
||||
tests/elementary/efl_ui_test_grid.c \
|
||||
tests/elementary/efl_ui_test_image.c \
|
||||
tests/elementary/efl_ui_test_image_zoomable.c \
|
||||
|
|
|
@ -155,6 +155,7 @@ elementary_test_src = [
|
|||
'test_win_indicator.c',
|
||||
'test_gesture_framework.c',
|
||||
'test_ui_tab_pager.c',
|
||||
'test_ui_relative_layout.c',
|
||||
'test.h'
|
||||
]
|
||||
|
||||
|
|
|
@ -377,6 +377,8 @@ void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info);
|
|||
void test_ui_pager(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_ui_pager_scroll(void *data, Evas_Object *obj, void *event_info);
|
||||
|
||||
void test_ui_relative_layout(void *data, Evas_Object *obj, void *event_info);
|
||||
|
||||
static void _list_udpate(void);
|
||||
|
||||
static Evas_Object *win, *tbx, *entry; // TODO: refactoring
|
||||
|
@ -842,6 +844,7 @@ add_tests:
|
|||
ADD_TEST_EO(NULL, "Containers", "Efl.Ui.Table", test_ui_table);
|
||||
ADD_TEST_EO(NULL, "Containers", "Efl.Ui.Table (Linear API)", test_ui_table_linear);
|
||||
ADD_TEST_EO(NULL, "Containers", "Efl.Ui.Table_Static", test_ui_table_static);
|
||||
ADD_TEST_EO(NULL, "Containers", "Efl.Ui.Relative_Layout", test_ui_relative_layout);
|
||||
|
||||
//------------------------------//
|
||||
ADD_TEST_EO(NULL, "Events", "Event Refeed", test_events);
|
||||
|
|
|
@ -0,0 +1,319 @@
|
|||
#include "test.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
#endif
|
||||
|
||||
#include <Elementary.h>
|
||||
|
||||
static Eo *layout, *btn1, *btn2, *btn3;
|
||||
|
||||
typedef enum {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
TOP,
|
||||
BOTTOM
|
||||
} Options;
|
||||
|
||||
static void
|
||||
_btn_clicked_to_cb(void *data, const Efl_Event *event)
|
||||
{
|
||||
Eo *to, *btn, *obj = event->object;
|
||||
Options opt = (Options)data;
|
||||
double relative;
|
||||
|
||||
btn = efl_key_wref_get(obj, "btn");
|
||||
to = efl_key_wref_get(obj, "to");
|
||||
|
||||
do
|
||||
{
|
||||
if (to == layout)
|
||||
to = btn1;
|
||||
else if (to == btn1)
|
||||
to = btn2;
|
||||
else if (to == btn2)
|
||||
to = btn3;
|
||||
else if (to == btn3)
|
||||
to = layout;
|
||||
}
|
||||
while (btn == to);
|
||||
efl_key_wref_set(obj, "to", to);
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case LEFT:
|
||||
efl_ui_relative_layout_relation_left_get(layout, btn, NULL, &relative);
|
||||
efl_ui_relative_layout_relation_left_set(layout, btn, to, relative);
|
||||
break;
|
||||
case RIGHT:
|
||||
efl_ui_relative_layout_relation_right_get(layout, btn, NULL, &relative);
|
||||
efl_ui_relative_layout_relation_right_set(layout, btn, to, relative);
|
||||
break;
|
||||
case TOP:
|
||||
efl_ui_relative_layout_relation_top_get(layout, btn, NULL, &relative);
|
||||
efl_ui_relative_layout_relation_top_set(layout, btn, to, relative);
|
||||
break;
|
||||
case BOTTOM:
|
||||
efl_ui_relative_layout_relation_bottom_get(layout, btn, NULL, &relative);
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, btn, to, relative);
|
||||
break;
|
||||
}
|
||||
efl_text_set(obj, ((to == layout) ? "parent" : (char *)efl_text_get(to)));
|
||||
efl_pack_layout_request(layout);
|
||||
}
|
||||
|
||||
static void
|
||||
_slider_changed_relative_cb(void *data, const Efl_Event *event)
|
||||
{
|
||||
Options opt = (Options)data;
|
||||
Eo *btn, *slider = event->object;
|
||||
double val;
|
||||
|
||||
btn = efl_key_wref_get(slider, "btn");
|
||||
val = efl_ui_range_value_get(slider);
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case LEFT:
|
||||
efl_ui_relative_layout_relation_left_set(layout, btn, NULL, val);
|
||||
break;
|
||||
case RIGHT:
|
||||
efl_ui_relative_layout_relation_right_set(layout, btn, NULL, val);
|
||||
break;
|
||||
case TOP:
|
||||
efl_ui_relative_layout_relation_top_set(layout, btn, NULL, val);
|
||||
break;
|
||||
case BOTTOM:
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, btn, NULL, val);
|
||||
break;
|
||||
}
|
||||
efl_pack_layout_request(layout);
|
||||
}
|
||||
|
||||
static void
|
||||
_slider_changed_align_cb(void *data, const Efl_Event *event)
|
||||
{
|
||||
char opt = (char)(uintptr_t)data;
|
||||
Eo *btn, *slider = event->object;
|
||||
double val, x, y;
|
||||
|
||||
btn = efl_key_wref_get(slider, "btn");
|
||||
val = efl_ui_range_value_get(slider);
|
||||
|
||||
efl_gfx_hint_align_get(btn, &x, &y);
|
||||
if (opt == 'x')
|
||||
efl_gfx_hint_align_set(btn, val, y);
|
||||
else if (opt == 'y')
|
||||
efl_gfx_hint_align_set(btn, x, val);
|
||||
|
||||
efl_pack_layout_request(layout);
|
||||
}
|
||||
|
||||
static void
|
||||
_setter_add(Eo *vbox, Eo *btn, Options option)
|
||||
{
|
||||
Eo *to, *hbox;
|
||||
char *text, *btn_text;
|
||||
double relative;
|
||||
|
||||
switch (option)
|
||||
{
|
||||
case LEFT:
|
||||
text = "left";
|
||||
efl_ui_relative_layout_relation_left_get(layout, btn, &to, &relative);
|
||||
break;
|
||||
case RIGHT:
|
||||
text = "right";
|
||||
efl_ui_relative_layout_relation_right_get(layout, btn, &to, &relative);
|
||||
break;
|
||||
case TOP:
|
||||
text = "top";
|
||||
efl_ui_relative_layout_relation_top_get(layout, btn, &to, &relative);
|
||||
break;
|
||||
case BOTTOM:
|
||||
text = "bottom";
|
||||
efl_ui_relative_layout_relation_bottom_get(layout, btn, &to, &relative);
|
||||
break;
|
||||
}
|
||||
btn_text = ((to == layout) ? "parent" : (char *)efl_text_get(to));
|
||||
|
||||
hbox = efl_add(EFL_UI_BOX_CLASS, vbox,
|
||||
efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL),
|
||||
efl_pack_padding_set(efl_added, 2, 2, EINA_TRUE),
|
||||
efl_pack(vbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_TEXT_CLASS, hbox,
|
||||
efl_text_set(efl_added, text),
|
||||
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
|
||||
efl_text_valign_set(efl_added, 0.5),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(40, 0)),
|
||||
efl_gfx_hint_weight_set(efl_added, 0, EFL_GFX_HINT_EXPAND),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_BUTTON_CLASS, hbox,
|
||||
efl_text_set(efl_added, btn_text),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(60, 0)),
|
||||
efl_key_wref_set(efl_added, "to", to),
|
||||
efl_key_wref_set(efl_added, "btn", btn),
|
||||
efl_gfx_hint_weight_set(efl_added, 0, EFL_GFX_HINT_EXPAND),
|
||||
efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _btn_clicked_to_cb, (void *)option),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_SLIDER_CLASS, hbox,
|
||||
efl_ui_range_min_max_set(efl_added, 0.0, 1.0),
|
||||
efl_ui_range_step_set(efl_added, 0.1),
|
||||
efl_ui_range_value_set(efl_added, relative),
|
||||
efl_key_wref_set(efl_added, "btn", btn),
|
||||
efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED, _slider_changed_relative_cb, (void *)option),
|
||||
efl_pack(hbox, efl_added));
|
||||
}
|
||||
|
||||
static void
|
||||
_button_frame_add(Eo *box, Eo *btn)
|
||||
{
|
||||
Eo *f, *vbox, *hbox;
|
||||
double align_x, align_y;
|
||||
|
||||
f = efl_add(EFL_UI_FRAME_CLASS, box,
|
||||
efl_text_set(efl_added, efl_text_get(btn)),
|
||||
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, 0),
|
||||
efl_pack(box, efl_added));
|
||||
|
||||
vbox = efl_add(EFL_UI_BOX_CLASS, f,
|
||||
efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL),
|
||||
efl_pack_padding_set(efl_added, 2, 2, EINA_TRUE),
|
||||
efl_gfx_hint_margin_set(efl_added, 2, 2, 2, 2),
|
||||
efl_content_set(f, efl_added));
|
||||
|
||||
hbox = efl_add(EFL_UI_BOX_CLASS, vbox,
|
||||
efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL),
|
||||
efl_pack_padding_set(efl_added, 2, 2, EINA_TRUE),
|
||||
efl_pack(vbox, efl_added));
|
||||
|
||||
efl_add(EFL_CANVAS_RECTANGLE_CLASS, hbox,
|
||||
efl_gfx_color_set(efl_added, 0, 0, 0, 0),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(40, 0)),
|
||||
efl_gfx_hint_weight_set(efl_added, 0, EFL_GFX_HINT_EXPAND),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_TEXT_CLASS, hbox,
|
||||
efl_text_set(efl_added, "to"),
|
||||
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
|
||||
efl_text_halign_set(efl_added, 0.5),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(60, 0)),
|
||||
efl_gfx_hint_weight_set(efl_added, 0, EFL_GFX_HINT_EXPAND),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_TEXT_CLASS, hbox,
|
||||
efl_text_set(efl_added, "relative"),
|
||||
efl_text_halign_set(efl_added, 0.5),
|
||||
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
_setter_add(vbox, btn, LEFT);
|
||||
_setter_add(vbox, btn, RIGHT);
|
||||
_setter_add(vbox, btn, TOP);
|
||||
_setter_add(vbox, btn, BOTTOM);
|
||||
|
||||
/* align setter */
|
||||
efl_gfx_hint_align_get(btn, &align_x, &align_y);
|
||||
|
||||
hbox = efl_add(EFL_UI_BOX_CLASS, vbox,
|
||||
efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL),
|
||||
efl_pack_padding_set(efl_added, 2, 2, EINA_TRUE),
|
||||
efl_pack(vbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_TEXT_CLASS, hbox,
|
||||
efl_text_set(efl_added, "align_x"),
|
||||
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(40, 0)),
|
||||
efl_gfx_hint_weight_set(efl_added, 0, EFL_GFX_HINT_EXPAND),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_SLIDER_CLASS, hbox,
|
||||
efl_ui_range_min_max_set(efl_added, 0.0, 1.0),
|
||||
efl_ui_range_step_set(efl_added, 0.1),
|
||||
efl_ui_range_value_set(efl_added, align_x),
|
||||
efl_key_wref_set(efl_added, "btn", btn),
|
||||
efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED, _slider_changed_align_cb, (void *)'x'),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
hbox = efl_add(EFL_UI_BOX_CLASS, vbox,
|
||||
efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL),
|
||||
efl_pack_padding_set(efl_added, 2, 2, EINA_TRUE),
|
||||
efl_pack(vbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_TEXT_CLASS, hbox,
|
||||
efl_text_set(efl_added, "align_y"),
|
||||
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(40, 0)),
|
||||
efl_gfx_hint_weight_set(efl_added, 0, EFL_GFX_HINT_EXPAND),
|
||||
efl_pack(hbox, efl_added));
|
||||
|
||||
efl_add(EFL_UI_SLIDER_CLASS, hbox,
|
||||
efl_ui_range_min_max_set(efl_added, 0.0, 1.0),
|
||||
efl_ui_range_step_set(efl_added, 0.1),
|
||||
efl_ui_range_value_set(efl_added, align_y),
|
||||
efl_key_wref_set(efl_added, "btn", btn),
|
||||
efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED, _slider_changed_align_cb, (void *)'y'),
|
||||
efl_pack(hbox, efl_added));
|
||||
}
|
||||
|
||||
void
|
||||
test_ui_relative_layout(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Eo *win, *vbox, *f, *hbox;
|
||||
|
||||
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
|
||||
efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
|
||||
efl_text_set(efl_added, "Efl.Ui.Relative_Layout"),
|
||||
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
|
||||
|
||||
vbox = efl_add(EFL_UI_BOX_CLASS, win,
|
||||
efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL),
|
||||
efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE),
|
||||
efl_gfx_hint_margin_set(efl_added, 5, 5, 5, 5),
|
||||
efl_content_set(win, efl_added));
|
||||
|
||||
/* controls */
|
||||
f = efl_add(EFL_UI_FRAME_CLASS, vbox,
|
||||
efl_text_set(efl_added, "Controls"),
|
||||
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, 0),
|
||||
efl_pack(vbox, efl_added));
|
||||
|
||||
hbox = efl_add(EFL_UI_BOX_CLASS, f,
|
||||
efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL),
|
||||
efl_pack_padding_set(efl_added, 10, 0, EINA_TRUE),
|
||||
efl_content_set(f, efl_added));
|
||||
|
||||
/* contents */
|
||||
f = efl_add(EFL_UI_FRAME_CLASS, vbox,
|
||||
efl_text_set(efl_added, "Contents"),
|
||||
efl_pack(vbox, efl_added));
|
||||
|
||||
layout = efl_add(EFL_UI_RELATIVE_LAYOUT_CLASS, f,
|
||||
efl_content_set(f, efl_added));
|
||||
|
||||
btn1 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "button1"),
|
||||
efl_gfx_hint_align_set(efl_added, 0.0, 0.0),
|
||||
efl_ui_relative_layout_relation_right_set(layout, efl_added, layout, 0.0),
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, efl_added, layout, 0.0));
|
||||
|
||||
btn2 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "button2"),
|
||||
efl_gfx_hint_align_set(efl_added, 0.5, 0.0),
|
||||
efl_ui_relative_layout_relation_left_set(layout, efl_added, btn1, 1.0),
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, efl_added, layout, 0.0));
|
||||
|
||||
btn3 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "button3"),
|
||||
efl_ui_relative_layout_relation_left_set(layout, efl_added, btn2, 0.0),
|
||||
efl_ui_relative_layout_relation_top_set(layout, efl_added, btn2, 1.0));
|
||||
|
||||
_button_frame_add(hbox, btn1);
|
||||
_button_frame_add(hbox, btn2);
|
||||
_button_frame_add(hbox, btn3);
|
||||
|
||||
efl_gfx_entity_size_set(win, EINA_SIZE2D(600, 400));
|
||||
efl_gfx_entity_visible_set(win, EINA_TRUE);
|
||||
}
|
|
@ -125,7 +125,9 @@ elementary/efl_ui_list_view_example_2.c \
|
|||
elementary/efl_ui_list_view_example_3.c \
|
||||
elementary/efl_canvas_layout_text.c \
|
||||
elementary/efl_ui_theme_example_01.c \
|
||||
elementary/efl_ui_theme_example_02.c
|
||||
elementary/efl_ui_theme_example_02.c \
|
||||
elementary/efl_ui_relative_layout_example_01.c \
|
||||
elementary/efl_ui_relative_layout_example_02.c
|
||||
|
||||
ELM_SRCS += \
|
||||
elementary/bg_cxx_example_01.cc \
|
||||
|
@ -344,7 +346,9 @@ elementary/efl_ui_list_view_example_2 \
|
|||
elementary/efl_ui_list_view_example_3 \
|
||||
elementary/efl_canvas_layout_text \
|
||||
elementary/efl_ui_theme_example_01 \
|
||||
elementary/efl_ui_theme_example_02
|
||||
elementary/efl_ui_theme_example_02 \
|
||||
elementary/efl_ui_relative_layout_example_01 \
|
||||
elementary/efl_ui_relative_layout_example_02
|
||||
#benchmark3d
|
||||
#sphere-hunter
|
||||
|
||||
|
|
|
@ -169,3 +169,5 @@
|
|||
/efl_ui_list_view_example_3
|
||||
/efl_ui_theme_example_01
|
||||
/efl_ui_theme_example_02
|
||||
/efl_ui_relative_layout_example_01
|
||||
/efl_ui_relative_layout_example_02
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// gcc -o efl_ui_relative_layout_example_01 efl_ui_relative_layout_example_01.c `pkg-config --cflags --libs elementary`
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "elementary_config.h"
|
||||
#else
|
||||
#define EFL_BETA_API_SUPPORT 1
|
||||
#define EFL_EO_API_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#include <Elementary.h>
|
||||
#include <Efl.h>
|
||||
|
||||
EAPI_MAIN int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
Eo *win, *layout, *btn1, *btn2, *btn3;
|
||||
|
||||
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
|
||||
efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
|
||||
efl_text_set(efl_added, "Efl.Ui.Relative_Layout"),
|
||||
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
|
||||
|
||||
layout = efl_add(EFL_UI_RELATIVE_LAYOUT_CLASS, win,
|
||||
efl_content_set(win, efl_added));
|
||||
|
||||
btn1 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "btn1"),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(100, 100)),
|
||||
efl_gfx_hint_align_set(efl_added, 0, 0),
|
||||
efl_gfx_hint_margin_set(efl_added, 10, 30, 20, 40),
|
||||
efl_ui_relative_layout_relation_right_set(layout, efl_added, layout, 0.0),
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, efl_added, layout, 0.0));
|
||||
|
||||
btn2 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "btn2"),
|
||||
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(0, 200)),
|
||||
efl_gfx_hint_align_set(efl_added, 0.5, 0),
|
||||
efl_ui_relative_layout_relation_left_set(layout, efl_added, btn1, 1.0),
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, efl_added, layout, 0.0));
|
||||
|
||||
btn3 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "btn3"),
|
||||
efl_ui_relative_layout_relation_left_set(layout, efl_added, btn2, 0.0),
|
||||
efl_ui_relative_layout_relation_top_set(layout, efl_added, btn2, 1.0));
|
||||
|
||||
efl_gfx_entity_size_set(win, EINA_SIZE2D(300, 300));
|
||||
|
||||
elm_run();
|
||||
return 0;
|
||||
}
|
||||
ELM_MAIN()
|
|
@ -0,0 +1,45 @@
|
|||
// gcc -o efl_ui_relative_layout_example_02 efl_ui_relative_layout_example_02.c `pkg-config --cflags --libs elementary`
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "elementary_config.h"
|
||||
#else
|
||||
#define EFL_BETA_API_SUPPORT 1
|
||||
#define EFL_EO_API_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#include <Elementary.h>
|
||||
#include <Efl.h>
|
||||
|
||||
EAPI_MAIN int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
Eo *win, *layout, *btn1, *btn2;
|
||||
|
||||
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
|
||||
efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
|
||||
efl_text_set(efl_added, "Efl.Ui.Relative_Layout"),
|
||||
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
|
||||
|
||||
layout = efl_add(EFL_UI_RELATIVE_LAYOUT_CLASS, win,
|
||||
efl_content_set(win, efl_added));
|
||||
|
||||
btn1 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "btn1"),
|
||||
efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(100, 100)));
|
||||
|
||||
btn2 = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_text_set(efl_added, "btn2"),
|
||||
efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(0, 100)));
|
||||
|
||||
efl_ui_relative_layout_relation_right_set(layout, btn1, btn2, 0.0);
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, btn1, btn2, 0.0);
|
||||
|
||||
efl_ui_relative_layout_relation_left_set(layout, btn2, btn1, 1.0);
|
||||
efl_ui_relative_layout_relation_top_set(layout, btn2, btn1, 1.0);
|
||||
|
||||
efl_gfx_entity_size_set(win, EINA_SIZE2D(300, 300));
|
||||
|
||||
elm_run();
|
||||
return 0;
|
||||
}
|
||||
ELM_MAIN()
|
|
@ -188,6 +188,7 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel);
|
|||
# include <efl_ui_win.eo.h>
|
||||
# include <efl_ui_win_inlined.eo.h>
|
||||
# include <efl_ui_win_socket.eo.h>
|
||||
# include <efl_ui_relative_layout.eo.h>
|
||||
|
||||
/* FIXME: Efl.Ui.Text must not use elm_general.h */
|
||||
# warning Efl.Ui.Text is not available yet without Elementary.h
|
||||
|
|
|
@ -360,6 +360,7 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel);
|
|||
# include <efl_ui_navigation_bar_part_back_button.eo.h>
|
||||
# include <efl_ui_navigation_layout.eo.h>
|
||||
# include <efl_ui_stack.eo.h>
|
||||
# include <efl_ui_relative_layout.eo.h>
|
||||
|
||||
# ifndef _EFL_UI_PAGER_EO_CLASS_TYPE
|
||||
# define _EFL_UI_PAGER_EO_CLASS_TYPE
|
||||
|
|
|
@ -0,0 +1,552 @@
|
|||
#include "efl_ui_relative_layout_private.h"
|
||||
|
||||
#define MY_CLASS EFL_UI_RELATIVE_LAYOUT_CLASS
|
||||
#define MY_CLASS_NAME "Efl.Ui.Relative_Layout"
|
||||
|
||||
#define LEFT 0
|
||||
#define RIGHT 1
|
||||
#define TOP 2
|
||||
#define BOTTOM 3
|
||||
|
||||
#define START (axis ? TOP : LEFT)
|
||||
#define END (axis ? BOTTOM : RIGHT)
|
||||
|
||||
static void _child_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis);
|
||||
|
||||
static int
|
||||
_chain_sort_cb(const void *l1, const void *l2)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Calc *calc1, *calc2;
|
||||
|
||||
calc1 = EINA_INLIST_CONTAINER_GET(l1, Efl_Ui_Relative_Layout_Calc);
|
||||
calc2 = EINA_INLIST_CONTAINER_GET(l2, Efl_Ui_Relative_Layout_Calc);
|
||||
|
||||
return calc2->comp_factor <= calc1->comp_factor ? -1 : 1;
|
||||
}
|
||||
|
||||
static Efl_Ui_Relative_Layout_Child *
|
||||
_efl_ui_relative_layout_register(Efl_Ui_Relative_Layout_Data *pd, Eo *child)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Child *rc;
|
||||
|
||||
rc = calloc(1, sizeof(Efl_Ui_Relative_Layout_Child));
|
||||
if (!rc) return NULL;
|
||||
|
||||
rc->obj = child;
|
||||
rc->layout = pd->obj;
|
||||
rc->rel[LEFT].to = rc->layout;
|
||||
rc->rel[LEFT].relative = 0.0;
|
||||
rc->rel[RIGHT].to = rc->layout;
|
||||
rc->rel[RIGHT].relative = 1.0;
|
||||
rc->rel[TOP].to = rc->layout;
|
||||
rc->rel[TOP].relative = 0.0;
|
||||
rc->rel[BOTTOM].to = rc->layout;
|
||||
rc->rel[BOTTOM].relative = 1.0;
|
||||
|
||||
if (pd->obj == child)
|
||||
{
|
||||
rc->calc.state[0] = RELATIVE_CALC_DONE;
|
||||
rc->calc.state[1] = RELATIVE_CALC_DONE;
|
||||
rc->calc.chain_state[0] = RELATIVE_CALC_DONE;
|
||||
rc->calc.chain_state[1] = RELATIVE_CALC_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
efl_ui_widget_sub_object_add(pd->obj, child);
|
||||
efl_canvas_group_member_add(pd->obj, child);
|
||||
efl_canvas_group_change(pd->obj);
|
||||
}
|
||||
|
||||
eina_hash_add(pd->children, &child, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Efl_Ui_Relative_Layout_Child *
|
||||
_relative_child_get(Efl_Ui_Relative_Layout_Data *pd, Eo *child)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Child *rc;
|
||||
|
||||
rc = eina_hash_find(pd->children, &child);
|
||||
if (!rc)
|
||||
rc = _efl_ui_relative_layout_register(pd, child);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Efl_Ui_Relative_Layout_Child *
|
||||
_relative_child_find(const Eina_Hash *children, Eo *target)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Child *child;
|
||||
|
||||
child = eina_hash_find(children, &target);
|
||||
if (!child)
|
||||
ERR("target(%p(%s)) is not registered", target, efl_class_name_get(target));
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_aspect_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Calc *calc = &child->calc;
|
||||
int temph;
|
||||
|
||||
if ((calc->aspect[0] <= 0) || (calc->aspect[1] <= 0))
|
||||
{
|
||||
ERR("Invalid aspect parameter for obj(%p), aspect(%d, %d) ",
|
||||
child->obj, calc->aspect[0], calc->aspect[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (calc->aspect_type)
|
||||
{
|
||||
case EFL_GFX_HINT_ASPECT_HORIZONTAL:
|
||||
if (axis) _child_calc(child, !axis);
|
||||
calc->want[1].length = calc->want[0].length * calc->aspect[1] / calc->aspect[0];
|
||||
break;
|
||||
case EFL_GFX_HINT_ASPECT_VERTICAL:
|
||||
if (!axis) _child_calc(child, !axis);
|
||||
calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1];
|
||||
break;
|
||||
case EFL_GFX_HINT_ASPECT_BOTH:
|
||||
if (calc->state[!axis] != RELATIVE_CALC_ON)
|
||||
_child_calc(child, !axis);
|
||||
temph = calc->want[axis].length * calc->aspect[!axis] / calc->aspect[axis];
|
||||
if (temph > calc->want[!axis].length)
|
||||
{
|
||||
temph = calc->want[!axis].length;
|
||||
calc->want[axis].length = temph * calc->aspect[axis] / calc->aspect[!axis];
|
||||
}
|
||||
else
|
||||
calc->want[!axis].length = temph;
|
||||
break;
|
||||
default:
|
||||
if (calc->state[!axis] != RELATIVE_CALC_ON)
|
||||
_child_calc(child, !axis);
|
||||
temph = calc->want[axis].length * calc->aspect[!axis] / calc->aspect[axis];
|
||||
if (temph < calc->want[!axis].length)
|
||||
{
|
||||
temph = calc->want[!axis].length;
|
||||
calc->want[axis].length = temph * calc->aspect[axis] / calc->aspect[!axis];
|
||||
}
|
||||
else
|
||||
calc->want[!axis].length = temph;
|
||||
}
|
||||
|
||||
//calculate max size
|
||||
if (calc->want[0].length > calc->max[0])
|
||||
{
|
||||
calc->want[0].length = calc->max[0];
|
||||
calc->want[1].length = calc->want[0].length * calc->aspect[1] / calc->aspect[0];
|
||||
}
|
||||
if (calc->want[1].length > calc->max[1])
|
||||
{
|
||||
calc->want[1].length = calc->max[1];
|
||||
calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1];
|
||||
}
|
||||
//calculate min size
|
||||
if (calc->want[0].length < calc->min[0])
|
||||
{
|
||||
calc->want[0].length = calc->min[0];
|
||||
calc->want[1].length = calc->want[0].length * calc->aspect[1] / calc->aspect[0];
|
||||
}
|
||||
if (calc->want[1].length < calc->min[1])
|
||||
{
|
||||
calc->want[1].length = calc->min[1];
|
||||
calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1];
|
||||
}
|
||||
|
||||
//calculate align
|
||||
calc->want[!axis].position =
|
||||
calc->space[!axis].position +
|
||||
(calc->space[!axis].length - calc->want[!axis].length) * calc->align[!axis];
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_child_chain_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Child *head, *tail, *o;
|
||||
Efl_Gfx_Hint_Aspect aspect_type;
|
||||
int space, min_sum = 0;
|
||||
double weight_sum = 0, cur_pos;
|
||||
Eina_Inlist *chain = NULL;
|
||||
|
||||
if (child->calc.chain_state[axis] == RELATIVE_CALC_DONE)
|
||||
return EINA_TRUE;
|
||||
|
||||
if ((child != child->calc.to[START]->calc.to[END]) &&
|
||||
(child != child->calc.to[END]->calc.to[START]))
|
||||
return EINA_FALSE;
|
||||
|
||||
// find head
|
||||
head = child;
|
||||
while (head == head->calc.to[START]->calc.to[END])
|
||||
head = head->calc.to[START];
|
||||
|
||||
//calculate weight_sum
|
||||
aspect_type = !axis ? EFL_GFX_HINT_ASPECT_VERTICAL : EFL_GFX_HINT_ASPECT_HORIZONTAL;
|
||||
o = head;
|
||||
do
|
||||
{
|
||||
if ((o->calc.aspect[0] > 0) && (o->calc.aspect[1] > 0) &&
|
||||
(o->calc.aspect_type == aspect_type))
|
||||
{
|
||||
_child_calc(o, !axis);
|
||||
if (o->calc.want[axis].length > o->calc.min[axis])
|
||||
o->calc.min[axis] = o->calc.want[axis].length;
|
||||
}
|
||||
else if ((o->calc.aspect[0] <= 0) ^ (o->calc.aspect[1] <= 0))
|
||||
{
|
||||
ERR("Invalid aspect parameter for obj(%p), aspect(%d, %d) ",
|
||||
o->obj, o->calc.aspect[0], o->calc.aspect[1]);
|
||||
}
|
||||
|
||||
o->calc.space[axis].length = o->calc.min[axis] +
|
||||
o->calc.margin[START] + o->calc.margin[END];
|
||||
min_sum += o->calc.space[axis].length;
|
||||
weight_sum += o->calc.weight[axis];
|
||||
|
||||
tail = o;
|
||||
o = o->calc.to[END];
|
||||
}
|
||||
while (o->calc.to[START] == tail);
|
||||
|
||||
_child_calc(head->calc.to[START], axis);
|
||||
_child_calc(tail->calc.to[END], axis);
|
||||
|
||||
cur_pos = head->calc.to[START]->calc.want[axis].position +
|
||||
(head->calc.to[START]->calc.want[axis].length * head->rel[START].relative);
|
||||
space = tail->calc.to[END]->calc.want[axis].position +
|
||||
(tail->calc.to[END]->calc.want[axis].length * tail->rel[END].relative) - cur_pos;
|
||||
|
||||
if ((space <= min_sum) || EINA_DBL_EQ(weight_sum, 0.0))
|
||||
cur_pos += (space - min_sum) * head->calc.align[axis];
|
||||
else
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Calc *calc;
|
||||
double weight_len, orig_space = space, orig_weight = weight_sum;
|
||||
|
||||
// Calculate compare factor
|
||||
for (o = head; o != tail->calc.to[END]; o = o->calc.to[END])
|
||||
{
|
||||
double denom;
|
||||
|
||||
calc = &o->calc;
|
||||
denom = (calc->weight[axis] * orig_space) - (orig_weight * calc->min[axis]);
|
||||
if (denom > 0)
|
||||
{
|
||||
calc->comp_factor = (calc->weight[axis] * orig_space) / denom;
|
||||
chain = eina_inlist_sorted_insert(chain, EINA_INLIST_GET(calc),
|
||||
_chain_sort_cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
space -= calc->space[axis].length;
|
||||
weight_sum -= calc->weight[axis];
|
||||
}
|
||||
}
|
||||
|
||||
EINA_INLIST_FOREACH(chain, calc)
|
||||
{
|
||||
weight_len = (space * calc->weight[axis]) / weight_sum;
|
||||
|
||||
if (calc->space[axis].length < weight_len)
|
||||
calc->space[axis].length = weight_len;
|
||||
else
|
||||
{
|
||||
weight_sum -= calc->weight[axis];
|
||||
space -= calc->space[axis].length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (o = head; o != tail->calc.to[END]; o = o->calc.to[END])
|
||||
{
|
||||
o->calc.space[axis].position = cur_pos + o->calc.margin[START] + 0.5;
|
||||
cur_pos += o->calc.space[axis].length;
|
||||
o->calc.space[axis].length -= o->calc.margin[START] + o->calc.margin[END];
|
||||
o->calc.chain_state[axis] = RELATIVE_CALC_DONE;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Calc *calc = &child->calc;
|
||||
|
||||
if (calc->state[axis] == RELATIVE_CALC_DONE)
|
||||
return;
|
||||
|
||||
if (calc->state[axis] == RELATIVE_CALC_ON)
|
||||
{
|
||||
ERR("%c-axis circular dependency when calculating part \"%s\"(%p).",
|
||||
axis ? 'Y' : 'X', efl_class_name_get(child->obj), child->obj);
|
||||
return;
|
||||
}
|
||||
|
||||
calc->state[axis] = RELATIVE_CALC_ON;
|
||||
|
||||
if (!_child_chain_calc(child, axis))
|
||||
{
|
||||
_child_calc(calc->to[START], axis);
|
||||
_child_calc(calc->to[END], axis);
|
||||
|
||||
calc->space[axis].position = calc->to[START]->calc.want[axis].position
|
||||
+ (calc->to[START]->calc.want[axis].length * child->rel[START].relative)
|
||||
+ calc->margin[START];
|
||||
calc->space[axis].length = calc->to[END]->calc.want[axis].position
|
||||
+ (calc->to[END]->calc.want[axis].length * child->rel[END].relative)
|
||||
- calc->margin[END] - calc->space[axis].position;
|
||||
}
|
||||
|
||||
if (calc->fill[axis] && (calc->weight[axis] > 0))
|
||||
calc->want[axis].length = calc->space[axis].length;
|
||||
|
||||
if (!calc->aspect[0] && !calc->aspect[1])
|
||||
{
|
||||
if (calc->want[axis].length > calc->max[axis])
|
||||
calc->want[axis].length = calc->max[axis];
|
||||
|
||||
if (calc->want[axis].length < calc->min[axis])
|
||||
calc->want[axis].length = calc->min[axis];
|
||||
}
|
||||
else
|
||||
{
|
||||
_child_aspect_calc(child, axis);
|
||||
}
|
||||
|
||||
//calculate align
|
||||
calc->want[axis].position =
|
||||
calc->space[axis].position +
|
||||
(calc->space[axis].length - calc->want[axis].length) * calc->align[axis];
|
||||
|
||||
child->calc.state[axis] = RELATIVE_CALC_DONE;
|
||||
}
|
||||
|
||||
static void
|
||||
_hash_free_cb(void *data)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Child *child = data;
|
||||
|
||||
free(child);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_hash_free_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
|
||||
void *data, void *fdata EINA_UNUSED)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Child *child = data;
|
||||
|
||||
_elm_widget_sub_object_redirect_to_top(child->layout, child->obj);
|
||||
_hash_free_cb(child);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
|
||||
void *data, void *fdata EINA_UNUSED)
|
||||
{
|
||||
Efl_Ui_Relative_Layout_Child *child = data;
|
||||
Eina_Rect want;
|
||||
|
||||
if (child->obj == child->layout)
|
||||
return EINA_TRUE;
|
||||
|
||||
_child_calc(child, 0);
|
||||
_child_calc(child, 1);
|
||||
|
||||
want.x = child->calc.want[0].position;
|
||||
want.w = child->calc.want[0].length;
|
||||
want.y = child->calc.want[1].position;
|
||||
want.h = child->calc.want[1].length;
|
||||
|
||||
efl_gfx_entity_geometry_set(child->obj, want);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
_hash_child_init_foreach_cb(const Eina_Hash *hash, const void *key EINA_UNUSED,
|
||||
void *data, void *fdata EINA_UNUSED)
|
||||
{
|
||||
Eina_Size2D max, min, aspect;
|
||||
Efl_Ui_Relative_Layout_Child *child = data;
|
||||
Efl_Ui_Relative_Layout_Calc *calc = &(child->calc);
|
||||
|
||||
calc->to[LEFT] = _relative_child_find(hash, child->rel[LEFT].to);
|
||||
if (!calc->to[LEFT]) calc->to[LEFT] = eina_hash_find(hash, &child->layout);
|
||||
calc->to[RIGHT] = _relative_child_find(hash, child->rel[RIGHT].to);
|
||||
if (!calc->to[RIGHT]) calc->to[RIGHT] = eina_hash_find(hash, &child->layout);
|
||||
calc->to[TOP] = _relative_child_find(hash, child->rel[TOP].to);
|
||||
if (!calc->to[TOP]) calc->to[TOP] = eina_hash_find(hash, &child->layout);
|
||||
calc->to[BOTTOM] = _relative_child_find(hash, child->rel[BOTTOM].to);
|
||||
if (!calc->to[BOTTOM]) calc->to[BOTTOM] = eina_hash_find(hash, &child->layout);
|
||||
|
||||
if (child->obj == child->layout)
|
||||
{
|
||||
Eina_Rect want = efl_gfx_entity_geometry_get(child->obj);
|
||||
calc->want[0].position = want.x;
|
||||
calc->want[0].length = want.w;
|
||||
calc->want[1].position = want.y;
|
||||
calc->want[1].length = want.h;
|
||||
calc->state[0] = RELATIVE_CALC_DONE;
|
||||
calc->state[1] = RELATIVE_CALC_DONE;
|
||||
calc->chain_state[0] = RELATIVE_CALC_DONE;
|
||||
calc->chain_state[1] = RELATIVE_CALC_DONE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
calc->state[0] = RELATIVE_CALC_NONE;
|
||||
calc->state[1] = RELATIVE_CALC_NONE;
|
||||
calc->chain_state[0] = RELATIVE_CALC_NONE;
|
||||
calc->chain_state[1] = RELATIVE_CALC_NONE;
|
||||
|
||||
efl_gfx_hint_weight_get(child->obj, &calc->weight[0], &calc->weight[1]);
|
||||
efl_gfx_hint_align_get(child->obj, &calc->align[0], &calc->align[1]);
|
||||
efl_gfx_hint_fill_get(child->obj, &calc->fill[0], &calc->fill[1]);
|
||||
efl_gfx_hint_aspect_get(child->obj, &calc->aspect_type, &aspect);
|
||||
calc->aspect[0] = aspect.w;
|
||||
calc->aspect[1] = aspect.h;
|
||||
efl_gfx_hint_margin_get(child->obj, &calc->margin[LEFT], &calc->margin[RIGHT],
|
||||
&calc->margin[TOP], &calc->margin[BOTTOM]);
|
||||
max = efl_gfx_hint_size_max_get(child->obj);
|
||||
min = efl_gfx_hint_size_combined_min_get(child->obj);
|
||||
calc->max[0] = max.w;
|
||||
calc->max[1] = max.h;
|
||||
calc->min[0] = min.w;
|
||||
calc->min[1] = min.h;
|
||||
|
||||
calc->want[0].position = 0;
|
||||
calc->want[0].length = 0;
|
||||
calc->want[1].position = 0;
|
||||
calc->want[1].length = 0;
|
||||
calc->space[0].position = 0;
|
||||
calc->space[0].length = 0;
|
||||
calc->space[1].position = 0;
|
||||
calc->space[1].length = 0;
|
||||
|
||||
if (calc->weight[0] < 0) calc->weight[0] = 0;
|
||||
if (calc->weight[1] < 0) calc->weight[1] = 0;
|
||||
|
||||
if (calc->align[0] < 0) calc->align[0] = 0;
|
||||
if (calc->align[1] < 0) calc->align[1] = 0;
|
||||
if (calc->align[0] > 1) calc->align[0] = 1;
|
||||
if (calc->align[1] > 1) calc->align[1] = 1;
|
||||
|
||||
if (calc->max[0] < 0) calc->max[0] = INT_MAX;
|
||||
if (calc->max[1] < 0) calc->max[1] = INT_MAX;
|
||||
if (calc->aspect[0] < 0) calc->aspect[0] = 0;
|
||||
if (calc->aspect[1] < 0) calc->aspect[1] = 0;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_on_size_hints_changed(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
|
||||
Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
efl_pack_layout_request(obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Relative_Layout_Data *pd)
|
||||
{
|
||||
eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, NULL);
|
||||
eina_hash_foreach(pd->children, _hash_child_calc_foreach_cb, NULL);
|
||||
|
||||
efl_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED)
|
||||
{
|
||||
efl_canvas_group_need_recalculate_set(obj, EINA_TRUE);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED)
|
||||
{
|
||||
efl_pack_layout_update(obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED, Eina_Size2D sz)
|
||||
{
|
||||
efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
|
||||
efl_canvas_group_change(obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED, Eina_Position2D pos)
|
||||
{
|
||||
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
|
||||
efl_canvas_group_change(obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED)
|
||||
{
|
||||
evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, NULL);
|
||||
efl_canvas_group_add(efl_super(obj, MY_CLASS));
|
||||
elm_widget_sub_object_parent_add(obj);
|
||||
|
||||
elm_widget_highlight_ignore_set(obj, EINA_TRUE);
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_efl_ui_relative_layout_efl_object_constructor(Eo *obj, Efl_Ui_Relative_Layout_Data *pd)
|
||||
{
|
||||
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
||||
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
|
||||
efl_access_object_access_type_set(obj, EFL_ACCESS_TYPE_SKIPPED);
|
||||
efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER);
|
||||
|
||||
pd->obj = obj;
|
||||
pd->children = eina_hash_pointer_new(_hash_free_cb);
|
||||
_efl_ui_relative_layout_register(pd, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_efl_object_destructor(Eo *obj, Efl_Ui_Relative_Layout_Data *pd)
|
||||
{
|
||||
eina_hash_free(pd->children);
|
||||
efl_destructor(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_unregister(Eo *obj, Efl_Ui_Relative_Layout_Data *pd, Efl_Object *child)
|
||||
{
|
||||
_elm_widget_sub_object_redirect_to_top(obj, child);
|
||||
if (!eina_hash_del_by_key(pd->children, &child))
|
||||
ERR("child(%p(%s)) is not registered", child, efl_class_name_get(child));
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_relative_layout_unregister_all(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd)
|
||||
{
|
||||
eina_hash_foreach(pd->children, _hash_free_foreach_cb, NULL);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Iterator *
|
||||
_efl_ui_relative_layout_children_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd)
|
||||
{
|
||||
return eina_hash_iterator_data_new(pd->children);
|
||||
}
|
||||
|
||||
EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(left, LEFT);
|
||||
EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(right, RIGHT);
|
||||
EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(top, TOP);
|
||||
EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(bottom, BOTTOM);
|
||||
|
||||
/* Internal EO APIs and hidden overrides */
|
||||
|
||||
#define EFL_UI_RELATIVE_LAYOUT_EXTRA_OPS \
|
||||
EFL_CANVAS_GROUP_ADD_OPS(efl_ui_relative_layout)
|
||||
|
||||
#include "efl_ui_relative_layout.eo.c"
|
|
@ -0,0 +1,79 @@
|
|||
class Efl.Ui.Relative_Layout extends Efl.Ui.Widget implements Efl.Pack_Layout
|
||||
{
|
||||
[[The relative layout class.
|
||||
|
||||
A relative layout calculates the size and position of all the children
|
||||
based on their relationship to each other.]]
|
||||
methods {
|
||||
@property relation_left {
|
||||
[[Specifies the left side edge of the child relative to the target.
|
||||
By default, target is parent and relative is 0.0.]]
|
||||
keys {
|
||||
child: Efl.Object; [[The child to specify relation.]]
|
||||
}
|
||||
values {
|
||||
target: Efl.Object; [[The relative target.]]
|
||||
relative: double; [[The ratio between left and right of the target,
|
||||
ranging from 0.0 to 1.0.]]
|
||||
}
|
||||
}
|
||||
@property relation_right {
|
||||
[[Specifies the right side edge of the child relative to the target.
|
||||
By default, target is parent and relative is 1.0.]]
|
||||
keys {
|
||||
child: Efl.Object; [[The child to specify relation.]]
|
||||
}
|
||||
values {
|
||||
target: Efl.Object; [[The relative target.]]
|
||||
relative: double; [[The ratio between left and right of the target,
|
||||
ranging from 0.0 to 1.0.]]
|
||||
}
|
||||
}
|
||||
@property relation_top {
|
||||
[[Specifies the top side edge of the child relative to the target.
|
||||
By default, target is parent and relative is 0.0.]]
|
||||
keys {
|
||||
child: Efl.Object; [[The child to specify relation.]]
|
||||
}
|
||||
values {
|
||||
target: Efl.Object; [[The relative target.]]
|
||||
relative: double; [[The ratio between top and bottom of the target,
|
||||
ranging from 0.0 to 1.0.]]
|
||||
}
|
||||
}
|
||||
@property relation_bottom {
|
||||
[[Specifies the bottom side edge of the child relative to the target.
|
||||
By default, target is parent and relative is 1.0.]]
|
||||
keys {
|
||||
child: Efl.Object; [[The child to specify relation.]]
|
||||
}
|
||||
values {
|
||||
target: Efl.Object; [[The relative target.]]
|
||||
relative: double; [[The ratio between top and bottom of the target,
|
||||
ranging from 0.0 to 1.0.]]
|
||||
}
|
||||
}
|
||||
unregister {
|
||||
[[Remove all relations of the child.]]
|
||||
params {
|
||||
@in child: Efl.Object; [[The child to unregister]]
|
||||
}
|
||||
}
|
||||
unregister_all {
|
||||
[[Remove all relations from the registered children. ]]
|
||||
}
|
||||
children_iterate {
|
||||
[[Begin iterating over this object's children.]]
|
||||
return: iterator<Efl.Object> @owned @warn_unused; [[Iterator to object children.]]
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Object.destructor;
|
||||
Efl.Canvas.Group.group_calculate;
|
||||
Efl.Gfx.Entity.position { set; }
|
||||
Efl.Gfx.Entity.size { set; }
|
||||
Efl.Pack_Layout.layout_update;
|
||||
Efl.Pack_Layout.layout_request;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef EFL_UI_RELATIVE_LAYOUT_PRIVATE_H
|
||||
#define EFL_UI_RELATIVE_LAYOUT_PRIVATE_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
#endif
|
||||
|
||||
#define EFL_PACK_LAYOUT_PROTECTED
|
||||
|
||||
#include <Elementary.h>
|
||||
#include "elm_priv.h"
|
||||
|
||||
typedef enum _Efl_Ui_Relative_Layout_Calc_State
|
||||
{
|
||||
RELATIVE_CALC_NONE,
|
||||
RELATIVE_CALC_DONE,
|
||||
RELATIVE_CALC_ON
|
||||
} Efl_Ui_Relative_Layout_Calc_State;
|
||||
|
||||
typedef struct _Efl_Ui_Relative_Layout_Data Efl_Ui_Relative_Layout_Data;
|
||||
typedef struct _Efl_Ui_Relative_Layout_Child Efl_Ui_Relative_Layout_Child;
|
||||
typedef struct _Efl_Ui_Relative_Layout_Calc Efl_Ui_Relative_Layout_Calc;
|
||||
typedef struct _Efl_Ui_Relative_Layout_Relation Efl_Ui_Relative_Layout_Relation;
|
||||
|
||||
struct _Efl_Ui_Relative_Layout_Calc
|
||||
{
|
||||
EINA_INLIST;
|
||||
|
||||
int max[2];
|
||||
int min[2];
|
||||
int aspect[2];
|
||||
int margin[4];
|
||||
Efl_Gfx_Hint_Aspect aspect_type;
|
||||
Eina_Bool fill[2];
|
||||
double weight[2];
|
||||
double align[2];
|
||||
double comp_factor;
|
||||
|
||||
struct {
|
||||
int position;
|
||||
double length;
|
||||
} space[2], want[2];
|
||||
|
||||
Efl_Ui_Relative_Layout_Calc_State state[2];
|
||||
Efl_Ui_Relative_Layout_Calc_State chain_state[2];
|
||||
Efl_Ui_Relative_Layout_Child *to[4];
|
||||
};
|
||||
|
||||
struct _Efl_Ui_Relative_Layout_Data
|
||||
{
|
||||
Eo *obj;
|
||||
Eina_Hash *children;
|
||||
};
|
||||
|
||||
struct _Efl_Ui_Relative_Layout_Relation
|
||||
{
|
||||
Efl_Object *to;
|
||||
double relative;
|
||||
};
|
||||
|
||||
struct _Efl_Ui_Relative_Layout_Child
|
||||
{
|
||||
Eo *obj;
|
||||
Eo *layout;
|
||||
Efl_Ui_Relative_Layout_Relation rel[4];
|
||||
Efl_Ui_Relative_Layout_Calc calc;
|
||||
};
|
||||
|
||||
#define EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(direction, DIRECTION) \
|
||||
EOLIAN static void \
|
||||
_efl_ui_relative_layout_relation_ ## direction ## _set(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd, Eo *child, Eo *target, double relative) \
|
||||
{ \
|
||||
Efl_Ui_Relative_Layout_Child *rc; \
|
||||
rc = _relative_child_get(pd, child); \
|
||||
if (target) rc->rel[DIRECTION].to = target; \
|
||||
if (relative < 0) relative = 0; \
|
||||
else if (relative > 1) relative = 1; \
|
||||
rc->rel[DIRECTION].relative = relative; \
|
||||
} \
|
||||
\
|
||||
EOLIAN static void \
|
||||
_efl_ui_relative_layout_relation_ ## direction ## _get(const Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd, Eo *child, Eo **target, double *relative) \
|
||||
{ \
|
||||
Efl_Ui_Relative_Layout_Child *rc; \
|
||||
rc = _relative_child_get(pd, child); \
|
||||
if (target) *target = rc->rel[DIRECTION].to; \
|
||||
if (relative) *relative = rc->rel[DIRECTION].relative; \
|
||||
}
|
||||
|
||||
#endif
|
|
@ -276,6 +276,7 @@ pub_eo_files = [
|
|||
'efl_ui_text_part.eo',
|
||||
'efl_ui_caching_factory.eo',
|
||||
'efl_ui_widget_factory.eo',
|
||||
'efl_ui_relative_layout.eo',
|
||||
]
|
||||
|
||||
foreach eo_file : pub_eo_files
|
||||
|
@ -480,7 +481,8 @@ elementary_headers_unstable = [
|
|||
'efl_page_indicator_icon.h',
|
||||
'efl_ui_tab_pager_private.h',
|
||||
'efl_ui_tab_bar_private.h',
|
||||
'efl_ui_tab_page_private.h'
|
||||
'efl_ui_tab_page_private.h',
|
||||
'efl_ui_relative_layout_private.h'
|
||||
]
|
||||
|
||||
elementary_pub_headers = [
|
||||
|
@ -912,6 +914,7 @@ elementary_src = [
|
|||
'efl_ui_homogeneous_model.c',
|
||||
'efl_ui_exact_model.c',
|
||||
'efl_ui_average_model.c'
|
||||
'efl_ui_relative_layout.c'
|
||||
]
|
||||
|
||||
elementary_deps = [emile, eo, efl, edje, ethumb, ethumb_client, emotion, ecore_imf, ecore_con, eldbus, efreet, efreet_mime, efreet_trash, eio, atspi, dl, intl]
|
||||
|
|
|
@ -14,6 +14,7 @@ static const Efl_Test_Case etc[] = {
|
|||
{ "efl_ui_focus_sub", efl_ui_test_focus_sub},
|
||||
{ "efl_ui_box", efl_ui_test_box},
|
||||
{ "efl_ui_grid", efl_ui_test_grid},
|
||||
{ "efl_ui_relative_layout", efl_ui_test_relative_layout},
|
||||
{ "efl_ui_image", efl_ui_test_image},
|
||||
{ "efl_ui_image_zoomable", efl_ui_test_image_zoomable},
|
||||
{ "efl_ui_layout", efl_ui_test_layout},
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
void efl_ui_test_box(TCase *tc);
|
||||
void efl_ui_test_grid(TCase *tc);
|
||||
void efl_ui_test_relative_layout(TCase *tc);
|
||||
void efl_ui_test_atspi(TCase *tc);
|
||||
void efl_ui_test_image_zoomable(TCase *tc);
|
||||
void efl_ui_test_layout(TCase *tc);
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
#endif
|
||||
|
||||
#include <Elementary.h>
|
||||
#include "elm_suite.h"
|
||||
|
||||
#define COORD_EQ(a, b) (!!(abs(a - b) < 2))
|
||||
#define GEOMETRY_EQ(a, b) (COORD_EQ(a.x, b.x) && COORD_EQ(a.y, b.y) && \
|
||||
COORD_EQ(a.w, b.w) && COORD_EQ(a.h, b.h))
|
||||
|
||||
typedef struct {
|
||||
Eina_Size2D max;
|
||||
Eina_Size2D min;
|
||||
double weightx;
|
||||
double weighty;
|
||||
double alignx;
|
||||
double aligny;
|
||||
int marginl;
|
||||
int marginr;
|
||||
int margint;
|
||||
int marginb;
|
||||
Efl_Gfx_Hint_Aspect mode;
|
||||
Eina_Size2D aspect;
|
||||
Eina_Bool fillx;
|
||||
Eina_Bool filly;
|
||||
Eina_Size2D layout_size;
|
||||
Eina_Size2D layout_expected;
|
||||
Eina_Rect expected;
|
||||
char testname[1024];
|
||||
} Hint;
|
||||
|
||||
static Hint hints[] = {
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(0, 0), 1, 1, 0.5, 0.5, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT(0, 0, 200, 200), "[0]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.3, 0.5, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT(0, 0, 200, 200), "[1]" },
|
||||
{ EINA_SIZE2D(50, 150), EINA_SIZE2D(70, 70), 1, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, (200 - 150) * 0.7, 70, 150), "[2]" },
|
||||
{ EINA_SIZE2D(150, -1), EINA_SIZE2D(70, 70), 0, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_FALSE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, (200 - 70) * 0.7, 70, 70), "[3]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_TRUE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, (200 - 70) * 0.7, 70, 70), "[4]" },
|
||||
{ EINA_SIZE2D(150, 150), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_TRUE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, (200 - 70) * 0.7, 70, 70), "[5]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 0, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, -7, 70, 70 * 3), "[6]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 0, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(300, 300), EINA_SIZE2D(300, 300),
|
||||
EINA_RECT((300 - 70) * 0.3, (300 - 70 * 3) * 0.7, 70, 70 * 3), "[7]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, -7, 70, 70 * 3), "[8]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(300, 300), EINA_SIZE2D(300, 300),
|
||||
EINA_RECT((300 - 70) * 0.3, (300 - 70 * 3) * 0.7, 70, 70 * 3), "[9]" },
|
||||
{ EINA_SIZE2D(-1, 150), EINA_SIZE2D(70, 70), 0, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, -7, 70, 70 * 3), "[10]" },
|
||||
{ EINA_SIZE2D(-1, 150), EINA_SIZE2D(70, 70), 0, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(300, 300), EINA_SIZE2D(300, 300),
|
||||
EINA_RECT((300 - 70) * 0.3, (300 - 70 * 3) * 0.7, 70, 70 * 3), "[11]" },
|
||||
{ EINA_SIZE2D(-1, 150), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(200, 200), EINA_SIZE2D(200, 200),
|
||||
EINA_RECT((200 - 70) * 0.3, -7, 70, 70 * 3), "[12]" },
|
||||
{ EINA_SIZE2D(-1, 150), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_BOTH, EINA_SIZE2D(1, 3), EINA_TRUE, EINA_FALSE,
|
||||
EINA_SIZE2D(300, 300), EINA_SIZE2D(300, 300),
|
||||
EINA_RECT((300 - 70) * 0.3, (300 - 70 * 3) * 0.7, 70, 70 * 3), "[13]" },
|
||||
};
|
||||
|
||||
static Hint hints2[][2] = {
|
||||
{
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_FALSE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT((150 - 70) * 0.3, (150 - 70) * 0.7, 70, 70), "[1/1 weight btn]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_FALSE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT((150 - 70) * 0.8, (150 - 70) * 0.2 + 150, 70, 70), "[1/1 weight btn2]" }
|
||||
},
|
||||
{
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_FALSE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT((150 - 70) * 0.3, 0, 70, 70), "[0/1 weight btn]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_FALSE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT((150 - 70) * 0.8, (300 - 140) * 0.2 + 70, 70, 70), "[0/1 weight btn2]" }
|
||||
},
|
||||
{
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 0, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_FALSE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT((150 - 70) * 0.3, (300 - 140) * 0.7, 70, 70), "[0/0 weight btn]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 0, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_FALSE, EINA_FALSE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT((150 - 70) * 0.8, (300 - 140) * 0.7 + 70, 70, 70), "[0/0 weight btn2]" }
|
||||
},
|
||||
};
|
||||
|
||||
static Hint hints3[][3] = {
|
||||
{
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT(0, 0, 150, 100), "[1/1/1 weight_l btn]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 100), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT(0, 100, 150, 100), "[1/1/1 weight_l btn2]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 300), EINA_SIZE2D(150, 300),
|
||||
EINA_RECT(0, 100 + 100, 150, 100), "[1/1/1 weight_l btn2]" }
|
||||
},
|
||||
{
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 270), EINA_SIZE2D(150, 270),
|
||||
EINA_RECT(0, 0, 150, 85), "[1/1/1 weight_m btn]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 100), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 270), EINA_SIZE2D(150, 270),
|
||||
EINA_RECT(0, 85, 150, 100), "[1/1/1 weight_m btn2]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 270), EINA_SIZE2D(150, 270),
|
||||
EINA_RECT(0, 100 + 85, 150, 85), "[1/1/1 weight_m btn2]" }
|
||||
},
|
||||
{
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.3, 0.7, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 200), EINA_SIZE2D(150, 200),
|
||||
EINA_RECT(0, -28, 150, 70), "[1/1/1 weight_s btn]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 100), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 200), EINA_SIZE2D(150, 200),
|
||||
EINA_RECT(0, 42, 150, 100), "[1/1/1 weight_s btn2]" },
|
||||
{ EINA_SIZE2D(-1, -1), EINA_SIZE2D(70, 70), 1, 1, 0.8, 0.2, 0, 0, 0, 0,
|
||||
EFL_GFX_HINT_ASPECT_NONE, EINA_SIZE2D(0, 0), EINA_TRUE, EINA_TRUE,
|
||||
EINA_SIZE2D(150, 200), EINA_SIZE2D(150, 200),
|
||||
EINA_RECT(0, 142, 150, 70), "[1/1/1 weight_s btn2]" }
|
||||
},
|
||||
};
|
||||
|
||||
static Eo *win, *layout;
|
||||
|
||||
static void
|
||||
btn_hint_set(Eo *btn, Hint *hint)
|
||||
{
|
||||
efl_gfx_entity_size_set(layout, hint->layout_size);
|
||||
efl_gfx_hint_size_max_set(btn, hint->max);
|
||||
efl_gfx_hint_size_min_set(btn, hint->min);
|
||||
efl_gfx_hint_margin_set(btn, hint->marginl, hint->marginr, hint->margint,
|
||||
hint->marginb);
|
||||
efl_gfx_hint_weight_set(btn, hint->weightx, hint->weighty);
|
||||
efl_gfx_hint_align_set(btn, hint->alignx, hint->aligny);
|
||||
efl_gfx_hint_fill_set(btn, hint->fillx, hint->filly);
|
||||
efl_gfx_hint_aspect_set(btn, hint->mode, hint->aspect);
|
||||
efl_canvas_group_calculate(layout);
|
||||
}
|
||||
|
||||
static void
|
||||
btn_geom_assert(Hint *hint, Eina_Rect btn_geom)
|
||||
{
|
||||
Eina_Size2D layout_size, layout_min;
|
||||
|
||||
layout_size = efl_gfx_entity_size_get(layout);
|
||||
layout_min = efl_gfx_hint_size_min_get(layout);
|
||||
layout_size.w = layout_size.w > layout_min.w ? layout_size.w : layout_min.w;
|
||||
layout_size.h = layout_size.h > layout_min.h ? layout_size.h : layout_min.h;
|
||||
|
||||
ck_assert_msg(GEOMETRY_EQ(btn_geom, hint->expected),
|
||||
"Case %s failed... button geometry: (%d, %d, %d, %d) expected geometry: (%d, %d, %d, %d)",
|
||||
hint->testname, btn_geom.x, btn_geom.y, btn_geom.w, btn_geom.h,
|
||||
hint->expected.x, hint->expected.y, hint->expected.w, hint->expected.h);
|
||||
ck_assert_msg(COORD_EQ(layout_size.w, hint->layout_expected.w) &&
|
||||
COORD_EQ(layout_size.h, hint->layout_expected.h),
|
||||
"Case %s failed... layout size: (%d, %d) expected size: (%d, %d)",
|
||||
hint->testname, layout_size.w, layout_size.h,
|
||||
hint->layout_expected.w, hint->layout_expected.h);
|
||||
}
|
||||
|
||||
static void
|
||||
layout_setup()
|
||||
{
|
||||
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
|
||||
efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC));
|
||||
|
||||
layout = efl_add(EFL_UI_RELATIVE_LAYOUT_CLASS, win,
|
||||
efl_gfx_entity_size_set(efl_added, EINA_SIZE2D(200, 200)));
|
||||
|
||||
efl_gfx_entity_size_set(win, EINA_SIZE2D(200, 200));
|
||||
}
|
||||
|
||||
static void
|
||||
layout_teardown()
|
||||
{
|
||||
if (win)
|
||||
{
|
||||
efl_del(win);
|
||||
win = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EFL_START_TEST (efl_ui_relative_layout_class_check)
|
||||
{
|
||||
const char *class;
|
||||
|
||||
class = efl_class_name_get(layout);
|
||||
|
||||
ck_assert(class != NULL);
|
||||
ck_assert(!strcmp(class, "Efl.Ui.Relative_Layout"));
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
EFL_START_TEST (efl_ui_relative_layout_layout_update)
|
||||
{
|
||||
int i, max_index = (sizeof(hints) / sizeof(Hint));
|
||||
|
||||
Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, layout,
|
||||
efl_ui_relative_layout_relation_left_set(layout, efl_added, NULL, 0.0));
|
||||
|
||||
for (i = 0; i < max_index; i++)
|
||||
{
|
||||
btn_hint_set(btn, &hints[i]);
|
||||
btn_geom_assert(&hints[i], efl_gfx_entity_geometry_get(btn));
|
||||
}
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
EFL_START_TEST (efl_ui_relative_layout_layout_update_chain)
|
||||
{
|
||||
int i, max_index2, max_index3;
|
||||
Eo *btn, *btn2, *btn3;
|
||||
|
||||
btn = efl_add(EFL_UI_BUTTON_CLASS, layout);
|
||||
btn2 = efl_add(EFL_UI_BUTTON_CLASS, layout);
|
||||
|
||||
max_index2 = ((sizeof(hints2) / sizeof(Hint)) / 2);
|
||||
max_index3 = ((sizeof(hints3) / sizeof(Hint)) / 3);
|
||||
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, btn, btn2, 0.0);
|
||||
efl_ui_relative_layout_relation_top_set(layout, btn2, btn, 1.0);
|
||||
|
||||
for (i = 0; i < max_index2; i++)
|
||||
{
|
||||
btn_hint_set(btn, &hints2[i][0]);
|
||||
btn_hint_set(btn2, &hints2[i][1]);
|
||||
btn_geom_assert(&hints2[i][0], efl_gfx_entity_geometry_get(btn));
|
||||
btn_geom_assert(&hints2[i][1], efl_gfx_entity_geometry_get(btn2));
|
||||
}
|
||||
|
||||
btn3 = efl_add(EFL_UI_BUTTON_CLASS, layout);
|
||||
efl_ui_relative_layout_relation_bottom_set(layout, btn2, btn3, 0.0);
|
||||
efl_ui_relative_layout_relation_top_set(layout, btn3, btn2, 1.0);
|
||||
|
||||
for (i = 0; i < max_index3; i++)
|
||||
{
|
||||
btn_hint_set(btn, &hints3[i][0]);
|
||||
btn_hint_set(btn2, &hints3[i][1]);
|
||||
btn_hint_set(btn3, &hints3[i][2]);
|
||||
btn_geom_assert(&hints3[i][0], efl_gfx_entity_geometry_get(btn));
|
||||
btn_geom_assert(&hints3[i][1], efl_gfx_entity_geometry_get(btn2));
|
||||
btn_geom_assert(&hints3[i][2], efl_gfx_entity_geometry_get(btn3));
|
||||
}
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
void efl_ui_test_relative_layout(TCase *tc)
|
||||
{
|
||||
tcase_add_checked_fixture(tc, layout_setup, layout_teardown);
|
||||
tcase_add_test(tc, efl_ui_relative_layout_class_check);
|
||||
tcase_add_test(tc, efl_ui_relative_layout_layout_update);
|
||||
tcase_add_test(tc, efl_ui_relative_layout_layout_update_chain);
|
||||
}
|
|
@ -124,6 +124,7 @@ efl_ui_suite_src = [
|
|||
'efl_ui_test_focus_sub.c',
|
||||
'efl_ui_test_box.c',
|
||||
'efl_ui_test_grid.c',
|
||||
'efl_ui_test_relative_layout.c',
|
||||
'efl_ui_test_image.c',
|
||||
'efl_ui_test_image_zoomable.c',
|
||||
'efl_ui_test_layout.c',
|
||||
|
|
Loading…
Reference in New Issue