aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/elementary
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/elementary')
-rw-r--r--src/lib/elementary/Efl_Ui.h30
-rw-r--r--src/lib/elementary/Elementary.h14
-rw-r--r--src/lib/elementary/efl_access_object.eo8
-rw-r--r--src/lib/elementary/efl_datetime_manager.c4
-rw-r--r--src/lib/elementary/efl_ui_action_connector.c (renamed from src/lib/elementary/efl_ui_clickable_util.c)39
-rw-r--r--src/lib/elementary/efl_ui_action_connector.eo (renamed from src/lib/elementary/efl_ui_clickable_util.eo)18
-rw-r--r--src/lib/elementary/efl_ui_alert_popup.c10
-rw-r--r--src/lib/elementary/efl_ui_anchor_popup.c351
-rw-r--r--src/lib/elementary/efl_ui_anchor_popup.eo42
-rw-r--r--src/lib/elementary/efl_ui_anchor_popup_private.h17
-rw-r--r--src/lib/elementary/efl_ui_animation_view.c1389
-rw-r--r--src/lib/elementary/efl_ui_animation_view.eo285
-rw-r--r--src/lib/elementary/efl_ui_animation_view.h33
-rw-r--r--src/lib/elementary/efl_ui_animation_view_eo.legacy.c162
-rw-r--r--src/lib/elementary/efl_ui_animation_view_eo.legacy.h517
-rw-r--r--src/lib/elementary/efl_ui_animation_view_legacy.h49
-rw-r--r--src/lib/elementary/efl_ui_animation_view_part.eo9
-rw-r--r--src/lib/elementary/efl_ui_animation_view_private.h42
-rw-r--r--src/lib/elementary/efl_ui_bg_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_box.c1
-rw-r--r--src/lib/elementary/efl_ui_box.eo2
-rw-r--r--src/lib/elementary/efl_ui_box_flow.c3
-rw-r--r--src/lib/elementary/efl_ui_button.c27
-rw-r--r--src/lib/elementary/efl_ui_button.eo2
-rw-r--r--src/lib/elementary/efl_ui_button_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_caching_factory.c174
-rw-r--r--src/lib/elementary/efl_ui_calendar.c30
-rw-r--r--src/lib/elementary/efl_ui_check.c47
-rw-r--r--src/lib/elementary/efl_ui_check.eo16
-rw-r--r--src/lib/elementary/efl_ui_check_eo.legacy.c4
-rw-r--r--src/lib/elementary/efl_ui_check_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_clickable.c120
-rw-r--r--src/lib/elementary/efl_ui_clickable.eo47
-rw-r--r--src/lib/elementary/efl_ui_clock.c354
-rw-r--r--src/lib/elementary/efl_ui_clock.eo2
-rw-r--r--src/lib/elementary/efl_ui_clock.h59
-rw-r--r--src/lib/elementary/efl_ui_collection.c1023
-rw-r--r--src/lib/elementary/efl_ui_collection.eo84
-rw-r--r--src/lib/elementary/efl_ui_collection_focus_manager.eo7
-rw-r--r--src/lib/elementary/efl_ui_container_layout.c2
-rw-r--r--src/lib/elementary/efl_ui_datepicker.c35
-rw-r--r--src/lib/elementary/efl_ui_default_item.c43
-rw-r--r--src/lib/elementary/efl_ui_default_item.eo30
-rw-r--r--src/lib/elementary/efl_ui_flip.c14
-rw-r--r--src/lib/elementary/efl_ui_focus_layer.c4
-rw-r--r--src/lib/elementary/efl_ui_focus_layer.eo2
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_calc.c82
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_root_focus.c24
-rw-r--r--src/lib/elementary/efl_ui_focus_parent_provider_gen.c4
-rw-r--r--src/lib/elementary/efl_ui_focus_util.eo6
-rw-r--r--src/lib/elementary/efl_ui_format.c6
-rw-r--r--src/lib/elementary/efl_ui_frame.c30
-rw-r--r--src/lib/elementary/efl_ui_frame.eo2
-rw-r--r--src/lib/elementary/efl_ui_frame_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_grid.c1111
-rw-r--r--src/lib/elementary/efl_ui_grid.eo96
-rw-r--r--src/lib/elementary/efl_ui_grid_default_item.c44
-rw-r--r--src/lib/elementary/efl_ui_grid_default_item.eo30
-rw-r--r--src/lib/elementary/efl_ui_grid_item.c83
-rw-r--r--src/lib/elementary/efl_ui_grid_item.eo12
-rw-r--r--src/lib/elementary/efl_ui_grid_item_private.h40
-rw-r--r--src/lib/elementary/efl_ui_grid_private.h83
-rw-r--r--src/lib/elementary/efl_ui_group_item.c303
-rw-r--r--src/lib/elementary/efl_ui_group_item.eo22
-rw-r--r--src/lib/elementary/efl_ui_image.c12
-rw-r--r--src/lib/elementary/efl_ui_image.eo2
-rw-r--r--src/lib/elementary/efl_ui_image_factory.c17
-rw-r--r--src/lib/elementary/efl_ui_image_zoomable.c26
-rw-r--r--src/lib/elementary/efl_ui_internal_text_scroller.c10
-rw-r--r--src/lib/elementary/efl_ui_internal_text_scroller.eo1
-rw-r--r--src/lib/elementary/efl_ui_item.c370
-rw-r--r--src/lib/elementary/efl_ui_item.eo54
-rw-r--r--src/lib/elementary/efl_ui_item_part_content.eo9
-rw-r--r--src/lib/elementary/efl_ui_item_part_extra.eo9
-rw-r--r--src/lib/elementary/efl_ui_item_part_icon.eo9
-rw-r--r--src/lib/elementary/efl_ui_item_part_text.eo11
-rw-r--r--src/lib/elementary/efl_ui_item_private.h7
-rw-r--r--src/lib/elementary/efl_ui_layout.c244
-rw-r--r--src/lib/elementary/efl_ui_layout.eo5
-rw-r--r--src/lib/elementary/efl_ui_layout_base.eo22
-rw-r--r--src/lib/elementary/efl_ui_layout_factory.c36
-rw-r--r--src/lib/elementary/efl_ui_layout_factory.eo1
-rw-r--r--src/lib/elementary/efl_ui_layout_legacy_eo.c39
-rw-r--r--src/lib/elementary/efl_ui_layout_legacy_eo.h2
-rw-r--r--src/lib/elementary/efl_ui_list.c1017
-rw-r--r--src/lib/elementary/efl_ui_list.eo85
-rw-r--r--src/lib/elementary/efl_ui_list_default_item.c42
-rw-r--r--src/lib/elementary/efl_ui_list_default_item.eo27
-rw-r--r--src/lib/elementary/efl_ui_list_item.c83
-rw-r--r--src/lib/elementary/efl_ui_list_item.eo12
-rw-r--r--src/lib/elementary/efl_ui_list_item_private.h30
-rw-r--r--src/lib/elementary/efl_ui_list_placeholder_item.c2
-rw-r--r--src/lib/elementary/efl_ui_list_placeholder_item.eo4
-rw-r--r--src/lib/elementary/efl_ui_list_private.h63
-rw-r--r--src/lib/elementary/efl_ui_list_view.c20
-rw-r--r--src/lib/elementary/efl_ui_list_view.eo2
-rw-r--r--src/lib/elementary/efl_ui_list_view_precise_layouter.c2
-rw-r--r--src/lib/elementary/efl_ui_multi_selectable.eo32
-rw-r--r--src/lib/elementary/efl_ui_navigation_bar.c6
-rw-r--r--src/lib/elementary/efl_ui_pan.c2
-rw-r--r--src/lib/elementary/efl_ui_pan.eo48
-rw-r--r--src/lib/elementary/efl_ui_panel.c258
-rw-r--r--src/lib/elementary/efl_ui_panel.eo7
-rw-r--r--src/lib/elementary/efl_ui_panel_private.h3
-rw-r--r--src/lib/elementary/efl_ui_panes.c28
-rw-r--r--src/lib/elementary/efl_ui_panes.eo3
-rw-r--r--src/lib/elementary/efl_ui_panes_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_popup.c476
-rw-r--r--src/lib/elementary/efl_ui_popup.eo27
-rw-r--r--src/lib/elementary/efl_ui_popup_part_backwall.eo3
-rw-r--r--src/lib/elementary/efl_ui_popup_private.h7
-rw-r--r--src/lib/elementary/efl_ui_position_manager_common.h80
-rw-r--r--src/lib/elementary/efl_ui_position_manager_entity.c14
-rw-r--r--src/lib/elementary/efl_ui_position_manager_entity.eo158
-rw-r--r--src/lib/elementary/efl_ui_position_manager_grid.c764
-rw-r--r--src/lib/elementary/efl_ui_position_manager_grid.eo18
-rw-r--r--src/lib/elementary/efl_ui_position_manager_list.c513
-rw-r--r--src/lib/elementary/efl_ui_position_manager_list.eo19
-rw-r--r--src/lib/elementary/efl_ui_progressbar.c62
-rw-r--r--src/lib/elementary/efl_ui_progressbar.eo3
-rw-r--r--src/lib/elementary/efl_ui_progressbar_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_property_bind_part.eo11
-rw-r--r--src/lib/elementary/efl_ui_radio.c47
-rw-r--r--src/lib/elementary/efl_ui_radio.eo2
-rw-r--r--src/lib/elementary/efl_ui_radio_group_impl.c8
-rw-r--r--src/lib/elementary/efl_ui_radio_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_relative_layout.c3
-rw-r--r--src/lib/elementary/efl_ui_scroll_alert_popup.c112
-rw-r--r--src/lib/elementary/efl_ui_scroll_alert_popup.eo22
-rw-r--r--src/lib/elementary/efl_ui_scroll_alert_popup_private.h2
-rw-r--r--src/lib/elementary/efl_ui_scroll_manager.c4
-rw-r--r--src/lib/elementary/efl_ui_scroll_util.c29
-rw-r--r--src/lib/elementary/efl_ui_scroller.c35
-rw-r--r--src/lib/elementary/efl_ui_scroller.eo1
-rw-r--r--src/lib/elementary/efl_ui_selectable.eo21
-rw-r--r--src/lib/elementary/efl_ui_selection_manager.c27
-rw-r--r--src/lib/elementary/efl_ui_selection_types.eot2
-rw-r--r--src/lib/elementary/efl_ui_single_selectable.eo17
-rw-r--r--src/lib/elementary/efl_ui_slider.c113
-rw-r--r--src/lib/elementary/efl_ui_slider.eo6
-rw-r--r--src/lib/elementary/efl_ui_slider_interval.c94
-rw-r--r--src/lib/elementary/efl_ui_spin.c71
-rw-r--r--src/lib/elementary/efl_ui_spin.eo11
-rw-r--r--src/lib/elementary/efl_ui_spin_button.c77
-rw-r--r--src/lib/elementary/efl_ui_spin_button.eo10
-rw-r--r--src/lib/elementary/efl_ui_spin_button_private.h4
-rw-r--r--src/lib/elementary/efl_ui_spin_private.h1
-rw-r--r--src/lib/elementary/efl_ui_spotlight_container.c43
-rw-r--r--src/lib/elementary/efl_ui_spotlight_manager_scroll.c29
-rw-r--r--src/lib/elementary/efl_ui_spotlight_manager_scroll.eo19
-rw-r--r--src/lib/elementary/efl_ui_spotlight_manager_stack.c4
-rw-r--r--src/lib/elementary/efl_ui_spotlight_manager_stack.eo2
-rw-r--r--src/lib/elementary/efl_ui_spotlight_util.c2
-rw-r--r--src/lib/elementary/efl_ui_spotlight_util.eo2
-rw-r--r--src/lib/elementary/efl_ui_table.c1
-rw-r--r--src/lib/elementary/efl_ui_table.eo2
-rw-r--r--src/lib/elementary/efl_ui_tags.c233
-rw-r--r--src/lib/elementary/efl_ui_text.c108
-rw-r--r--src/lib/elementary/efl_ui_text.eo29
-rw-r--r--src/lib/elementary/efl_ui_text_alert_popup.c121
-rw-r--r--src/lib/elementary/efl_ui_text_alert_popup.eo16
-rw-r--r--src/lib/elementary/efl_ui_text_alert_popup_private.h2
-rw-r--r--src/lib/elementary/efl_ui_textpath.c171
-rw-r--r--src/lib/elementary/efl_ui_textpath.eo7
-rw-r--r--src/lib/elementary/efl_ui_textpath_eo.legacy.c5
-rw-r--r--src/lib/elementary/efl_ui_textpath_eo.legacy.h8
-rw-r--r--src/lib/elementary/efl_ui_textpath_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_theme.eo2
-rw-r--r--src/lib/elementary/efl_ui_timepicker.c31
-rw-r--r--src/lib/elementary/efl_ui_video.c8
-rw-r--r--src/lib/elementary/efl_ui_video.eo1
-rw-r--r--src/lib/elementary/efl_ui_video_legacy_eo.c2
-rw-r--r--src/lib/elementary/efl_ui_widget.c298
-rw-r--r--src/lib/elementary/efl_ui_widget.eo4
-rw-r--r--src/lib/elementary/efl_ui_widget_factory.c217
-rw-r--r--src/lib/elementary/efl_ui_widget_factory.eo4
-rw-r--r--src/lib/elementary/efl_ui_widget_part.eo3
-rw-r--r--src/lib/elementary/efl_ui_win.c80
-rw-r--r--src/lib/elementary/efl_ui_win.eo42
-rw-r--r--src/lib/elementary/efl_ui_win_legacy_eo.c2
-rw-r--r--src/lib/elementary/elc_combobox.c2
-rw-r--r--src/lib/elementary/elc_ctxpopup.c13
-rw-r--r--src/lib/elementary/elc_fileselector.c2
-rw-r--r--src/lib/elementary/elc_fileselector_entry.c14
-rw-r--r--src/lib/elementary/elc_hoversel.c10
-rw-r--r--src/lib/elementary/elc_multibuttonentry.c18
-rw-r--r--src/lib/elementary/elc_naviframe.c6
-rw-r--r--src/lib/elementary/elc_player.c18
-rw-r--r--src/lib/elementary/elc_popup.c4
-rw-r--r--src/lib/elementary/elm_actionslider.c26
-rw-r--r--src/lib/elementary/elm_actionslider_eo.c2
-rw-r--r--src/lib/elementary/elm_box.c1
-rw-r--r--src/lib/elementary/elm_bubble.c14
-rw-r--r--src/lib/elementary/elm_bubble_eo.c2
-rw-r--r--src/lib/elementary/elm_calendar.c32
-rw-r--r--src/lib/elementary/elm_calendar_eo.c2
-rw-r--r--src/lib/elementary/elm_clock_eo.c2
-rw-r--r--src/lib/elementary/elm_code_widget.c2
-rw-r--r--src/lib/elementary/elm_code_widget_legacy_eo.c2
-rw-r--r--src/lib/elementary/elm_color_class.c2
-rw-r--r--src/lib/elementary/elm_colorselector.c67
-rw-r--r--src/lib/elementary/elm_colorselector_eo.c2
-rw-r--r--src/lib/elementary/elm_config.c255
-rw-r--r--src/lib/elementary/elm_conformant_eo.c2
-rw-r--r--src/lib/elementary/elm_ctxpopup_eo.c2
-rw-r--r--src/lib/elementary/elm_dayselector.c14
-rw-r--r--src/lib/elementary/elm_dayselector_eo.c2
-rw-r--r--src/lib/elementary/elm_deprecated.h16
-rw-r--r--src/lib/elementary/elm_diskselector_eo.c2
-rw-r--r--src/lib/elementary/elm_entry.c20
-rw-r--r--src/lib/elementary/elm_entry_eo.c2
-rw-r--r--src/lib/elementary/elm_fileselector_button_eo.c2
-rw-r--r--src/lib/elementary/elm_fileselector_entry_eo.c2
-rw-r--r--src/lib/elementary/elm_fileselector_eo.c2
-rw-r--r--src/lib/elementary/elm_flipselector.c5
-rw-r--r--src/lib/elementary/elm_flipselector_eo.c2
-rw-r--r--src/lib/elementary/elm_focus_legacy.c11
-rw-r--r--src/lib/elementary/elm_gengrid.c9
-rw-r--r--src/lib/elementary/elm_gengrid_eo.c2
-rw-r--r--src/lib/elementary/elm_genlist.c5
-rw-r--r--src/lib/elementary/elm_genlist_eo.c2
-rw-r--r--src/lib/elementary/elm_glview.c2
-rw-r--r--src/lib/elementary/elm_hover.c4
-rw-r--r--src/lib/elementary/elm_hover_eo.c2
-rw-r--r--src/lib/elementary/elm_hoversel_eo.c2
-rw-r--r--src/lib/elementary/elm_index.c12
-rw-r--r--src/lib/elementary/elm_index_eo.c2
-rw-r--r--src/lib/elementary/elm_interface_scrollable.c5
-rw-r--r--src/lib/elementary/elm_inwin.c18
-rw-r--r--src/lib/elementary/elm_inwin_eo.c2
-rw-r--r--src/lib/elementary/elm_label.c4
-rw-r--r--src/lib/elementary/elm_label_eo.c2
-rw-r--r--src/lib/elementary/elm_list.c16
-rw-r--r--src/lib/elementary/elm_list_eo.c2
-rw-r--r--src/lib/elementary/elm_main.c1
-rw-r--r--src/lib/elementary/elm_map.c13
-rw-r--r--src/lib/elementary/elm_map_eo.c2
-rw-r--r--src/lib/elementary/elm_menu.c6
-rw-r--r--src/lib/elementary/elm_menu_eo.c2
-rw-r--r--src/lib/elementary/elm_multibuttonentry_eo.c2
-rw-r--r--src/lib/elementary/elm_naviframe_eo.c2
-rw-r--r--src/lib/elementary/elm_panel.c21
-rw-r--r--src/lib/elementary/elm_panel_eo.c2
-rw-r--r--src/lib/elementary/elm_photo_eo.c2
-rw-r--r--src/lib/elementary/elm_player_eo.c2
-rw-r--r--src/lib/elementary/elm_plug_eo.c2
-rw-r--r--src/lib/elementary/elm_popup_eo.c2
-rw-r--r--src/lib/elementary/elm_prefs.c12
-rw-r--r--src/lib/elementary/elm_priv.h13
-rw-r--r--src/lib/elementary/elm_route_eo.c2
-rw-r--r--src/lib/elementary/elm_scroller.c4
-rw-r--r--src/lib/elementary/elm_scroller_eo.c2
-rw-r--r--src/lib/elementary/elm_segment_control.c25
-rw-r--r--src/lib/elementary/elm_segment_control_eo.c2
-rw-r--r--src/lib/elementary/elm_separator.c15
-rw-r--r--src/lib/elementary/elm_separator_eo.c2
-rw-r--r--src/lib/elementary/elm_slider.c855
-rw-r--r--src/lib/elementary/elm_slider_eo.c2
-rw-r--r--src/lib/elementary/elm_slideshow.c13
-rw-r--r--src/lib/elementary/elm_slideshow_eo.c2
-rw-r--r--src/lib/elementary/elm_spinner.c23
-rw-r--r--src/lib/elementary/elm_spinner_eo.c2
-rw-r--r--src/lib/elementary/elm_table.c1
-rw-r--r--src/lib/elementary/elm_theme.c23
-rw-r--r--src/lib/elementary/elm_thumb_eo.c2
-rw-r--r--src/lib/elementary/elm_toolbar.c79
-rw-r--r--src/lib/elementary/elm_toolbar_eo.c2
-rw-r--r--src/lib/elementary/elm_util.c4
-rw-r--r--src/lib/elementary/elm_widget.h9
-rw-r--r--src/lib/elementary/elm_widget_layout.h17
-rw-r--r--src/lib/elementary/elm_widget_slider.h13
-rw-r--r--src/lib/elementary/meson.build45
272 files changed, 9440 insertions, 6640 deletions
diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h
index 6ef6a65049..85cc93f7ce 100644
--- a/src/lib/elementary/Efl_Ui.h
+++ b/src/lib/elementary/Efl_Ui.h
@@ -21,7 +21,9 @@
#ifdef ELM_DIRENT_H
#include <dirent.h>
#endif
-#include <pwd.h>
+#ifndef _WIN32
+# include <pwd.h>
+#endif
#include <errno.h>
#ifdef ELM_UNIX
@@ -180,6 +182,8 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel);
# include <efl_ui_layout_part_text.eo.h>
# include <efl_ui_layout_part_table.eo.h>
# include <efl_ui_item.eo.h>
+# include <efl_ui_default_item.eo.h>
+# include <efl_ui_group_item.eo.h>
# include <efl_ui_win_part.eo.h>
# include <efl_ui_bg.eo.h>
# include <efl_ui_box.eo.h>
@@ -205,6 +209,8 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel);
# include <efl_ui_text_async.eo.h>
# endif
+# include <efl_ui_animation_view.h>
+# include <efl_ui_animation_view_part.eo.h>
# include <efl_ui_clock.h>
# include <efl_ui_image_factory.eo.h>
# include <efl_ui_video.h>
@@ -244,13 +250,29 @@ typedef Eo Efl_Ui_Spotlight_Indicator;
# include <efl_ui_navigation_bar_part.eo.h>
# include <efl_ui_navigation_bar_part_back_button.eo.h>
# include <efl_ui_navigation_layout.eo.h>
-# include <efl_ui_clickable.eo.h>
-# include <efl_ui_clickable_util.eo.h>
+# include <efl_ui_action_connector.eo.h>
# include <efl_ui_format.eo.h>
# include <efl_ui_spin.eo.h>
# include <efl_ui_spin_button.eo.h>
# include <efl_ui_slider.eo.h>
-
+# include <efl_ui_item.eo.h>
+# include <efl_ui_position_manager_entity.eo.h>
+# include <efl_ui_collection.eo.h>
+# include <efl_ui_position_manager_list.eo.h>
+# include <efl_ui_position_manager_grid.eo.h>
+# include <efl_ui_list_default_item.eo.h>
+# include <efl_ui_grid_default_item.eo.h>
+# include <efl_ui_list_placeholder_item.eo.h>
+# include <efl_ui_selectable.eo.h>
+# include <efl_ui_single_selectable.eo.h>
+# include <efl_ui_multi_selectable.eo.h>
+# include <efl_ui_popup.eo.h>
+# 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_popup_part_backwall.eo.h>
+# include <efl_ui_grid.eo.h>
+# include <efl_ui_list.eo.h>
/**
* Initialize Elementary
*
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 3316529acc..0a4b321fa4 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -27,7 +27,9 @@
#ifdef ELM_DIRENT_H
#include <dirent.h>
#endif
-#include <pwd.h>
+#ifndef _WIN32
+# include <pwd.h>
+#endif
#include <errno.h>
#ifdef ELM_UNIX
@@ -167,7 +169,6 @@ typedef Eo Efl_Ui_Focus_Manager;
#ifdef EFL_BETA_API_SUPPORT
# include <elm_interface_scrollable.h>
# include <elm_interface_scrollable.eo.h>
-#include <efl_ui_clickable.eo.h>
#endif
#include <elm_tooltip.h>
@@ -211,6 +212,7 @@ typedef Eo Efl_Ui_Focus_Manager;
#include <elm_button.h>
#include <elm_cache.h>
#include <elm_calendar.h>
+#include <efl_ui_animation_view.h>
#include <efl_ui_calendar.h>
#include <elm_check.h>
#include <elm_clock.h>
@@ -311,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>
@@ -329,16 +330,10 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_slider.eo.h>
# include <efl_ui_slider_interval.eo.h>
# include <efl_ui_layout_factory.eo.h>
-# include <efl_ui_item_part_text.eo.h>
-# include <efl_ui_item_part_icon.eo.h>
-# include <efl_ui_item_part_extra.eo.h>
-# include <efl_ui_item_part_content.eo.h>
# include <efl_ui_item.eo.h>
-# include <efl_ui_list_item.eo.h>
# include <efl_ui_list_default_item.eo.h>
# include <efl_ui_list_placeholder_item.eo.h>
# include <efl_ui_list.eo.h>
-# include <efl_ui_grid_item.eo.h>
# include <efl_ui_grid_default_item.eo.h>
# include <efl_ui_grid.eo.h>
# include <efl_ui_list_view_types.eot.h>
@@ -355,6 +350,7 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_dnd.eo.h>
# include <efl_ui_dnd_container.eo.h>
# include <efl_ui_relative_layout.eo.h>
+# include <efl_ui_animation_view.eo.h>
# include <efl_ui_tab_bar.eo.h>
# include <efl_ui_tab_page.eo.h>
# include <efl_ui_tab_page_part_tab.eo.h>
diff --git a/src/lib/elementary/efl_access_object.eo b/src/lib/elementary/efl_access_object.eo
index 9e7dc5da0f..8f23a9d995 100644
--- a/src/lib/elementary/efl_access_object.eo
+++ b/src/lib/elementary/efl_access_object.eo
@@ -358,7 +358,7 @@ mixin @beta Efl.Access.Object requires Efl.Object
states: Efl.Access.State_Set; [[Accessible state set]]
}
}
- event_handler_add @class @protected @beta {
+ event_handler_add @static @protected @beta {
[[Register accessibility event listener]]
params {
@in cb: Efl.Event_Cb; [[Callback]]
@@ -366,13 +366,13 @@ mixin @beta Efl.Access.Object requires Efl.Object
}
return: ptr(Efl.Access.Event.Handler); [[Event handler]]
}
- event_handler_del @class @protected @beta {
+ event_handler_del @static @protected @beta {
[[Deregister accessibility event listener]]
params {
@in handler: ptr(Efl.Access.Event.Handler); [[Event handler]]
}
}
- event_emit @class @protected @beta {
+ event_emit @static @protected @beta {
[[Emit event]]
params {
@in accessible: Efl.Access.Object; [[Accessibility object.]]
@@ -445,7 +445,7 @@ mixin @beta Efl.Access.Object requires Efl.Object
relationships_clear @beta {
[[Removes all relationships in accessible object.]]
}
- @property access_root @class @beta {
+ @property access_root @static @beta {
get {
[[Get root object of accessible object hierarchy]]
values {
diff --git a/src/lib/elementary/efl_datetime_manager.c b/src/lib/elementary/efl_datetime_manager.c
index 8739be8251..24daa34217 100644
--- a/src/lib/elementary/efl_datetime_manager.c
+++ b/src/lib/elementary/efl_datetime_manager.c
@@ -5,6 +5,10 @@
# include <langinfo.h>
#endif
+#ifdef _WIN32
+# include <evil_private.h> /* nl_langinfo */
+#endif
+
#include <Elementary.h>
#include "elm_priv.h"
diff --git a/src/lib/elementary/efl_ui_clickable_util.c b/src/lib/elementary/efl_ui_action_connector.c
index 3243b725bb..2d3dace64a 100644
--- a/src/lib/elementary/efl_ui_clickable_util.c
+++ b/src/lib/elementary/efl_ui_action_connector.c
@@ -2,14 +2,14 @@
# include <config.h>
#endif
-#define EFL_UI_CLICKABLE_PROTECTED 1
+#define EFL_INPUT_CLICKABLE_PROTECTED 1
#include <Efl_Ui.h>
#include "elm_priv.h"
typedef struct {
-} Efl_Ui_Clickable_Util_Data;
+} Efl_Ui_Action_Connector_Data;
static void
_on_press_cb(void *data,
@@ -17,7 +17,7 @@ _on_press_cb(void *data,
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
- efl_ui_clickable_press(data, 1);
+ efl_input_clickable_press(data, 1);
}
static void
@@ -26,7 +26,7 @@ _on_unpress_cb(void *data,
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
- efl_ui_clickable_unpress(data, 1);
+ efl_input_clickable_unpress(data, 1);
}
static void
@@ -35,7 +35,7 @@ _on_mouse_out(void *data,
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
- efl_ui_clickable_button_state_reset(data, 1);
+ efl_input_clickable_button_state_reset(data, 1);
}
static void
@@ -44,17 +44,17 @@ _theme_move_cb(void *data, const Efl_Event *ev EINA_UNUSED)
Efl_Input_Pointer *pointer = ev->info;
if (efl_input_processed_get(pointer))
- efl_ui_clickable_button_state_reset(data, 1);
+ efl_input_clickable_button_state_reset(data, 1);
}
-EFL_CALLBACKS_ARRAY_DEFINE(bind_to_theme_callbacks,
+EFL_CALLBACKS_ARRAY_DEFINE(bind_clickable_to_theme_callbacks,
{EFL_EVENT_POINTER_MOVE, _theme_move_cb},
)
EOLIAN static void
-_efl_ui_clickable_util_bind_to_theme(Efl_Canvas_Layout *object, Efl_Ui_Clickable *clickable)
+_efl_ui_action_connector_bind_clickable_to_theme(Efl_Canvas_Layout *object, Efl_Input_Clickable *clickable)
{
- efl_event_callback_array_add(object, bind_to_theme_callbacks(), clickable);
+ efl_event_callback_array_add(object, bind_clickable_to_theme_callbacks(), clickable);
efl_layout_signal_callback_add(object, "efl,action,press", "*", clickable, _on_press_cb, NULL);
efl_layout_signal_callback_add(object, "efl,action,unpress", "*", clickable, _on_unpress_cb, NULL);
@@ -67,8 +67,7 @@ _press_cb(void *data, const Efl_Event *ev)
Efl_Input_Pointer *pointer = ev->info;
if (!efl_input_processed_get(pointer))
{
- efl_ui_clickable_press(data, 1);
- efl_input_processed_set(pointer, EINA_TRUE);
+ efl_input_clickable_press(data, 1);
}
}
@@ -80,35 +79,33 @@ _unpress_cb(void *data, const Efl_Event *ev EINA_UNUSED)
Eina_Rect geom = efl_gfx_entity_geometry_get(data);
if (efl_input_processed_get(pointer))
{
- efl_ui_clickable_button_state_reset(data, 1);
+ efl_input_clickable_button_state_reset(data, 1);
}
else if (!eina_rectangle_coords_inside(&geom.rect, mouse_pos.x, mouse_pos.y))
{
//we are emulating edje behavior here, do press unpress on the event, but not click
- efl_ui_clickable_button_state_reset(data, 1);
+ efl_input_clickable_button_state_reset(data, 1);
if (efl_canvas_object_pointer_mode_get(data) == EFL_INPUT_OBJECT_POINTER_MODE_AUTO_GRAB)
{
- efl_ui_clickable_unpress(data, 1);
- efl_input_processed_set(pointer, EINA_TRUE);
+ efl_input_clickable_unpress(data, 1);
}
}
else
{
- efl_ui_clickable_unpress(data, 1);
- efl_input_processed_set(pointer, EINA_TRUE);
+ efl_input_clickable_unpress(data, 1);
}
}
-EFL_CALLBACKS_ARRAY_DEFINE(bind_to_object_callbacks,
+EFL_CALLBACKS_ARRAY_DEFINE(bind_clickable_to_object_callbacks,
{EFL_EVENT_POINTER_DOWN, _press_cb},
{EFL_EVENT_POINTER_UP, _unpress_cb},
)
EOLIAN static void
-_efl_ui_clickable_util_bind_to_object(Efl_Input_Interface *object, Efl_Ui_Clickable *clickable)
+_efl_ui_action_connector_bind_clickable_to_object(Efl_Input_Interface *object, Efl_Input_Clickable *clickable)
{
- efl_event_callback_array_add(object, bind_to_object_callbacks(), clickable);
+ efl_event_callback_array_add(object, bind_clickable_to_object_callbacks(), clickable);
}
-#include "efl_ui_clickable_util.eo.c"
+#include "efl_ui_action_connector.eo.c"
diff --git a/src/lib/elementary/efl_ui_clickable_util.eo b/src/lib/elementary/efl_ui_action_connector.eo
index d086c24581..1c3f4f7ee2 100644
--- a/src/lib/elementary/efl_ui_clickable_util.eo
+++ b/src/lib/elementary/efl_ui_action_connector.eo
@@ -1,12 +1,12 @@
-class @beta Efl.Ui.Clickable_Util {
- [[Helper class that connects theme signals or object events to the @Efl.Ui.Clickable interface.
+class @beta Efl.Ui.Action_Connector {
+ [[Helper class that connects theme signals or object events to the interfaces which are for actions.
- This simplifies creating widgets that implement the @Efl.Ui.Clickable interface.
+ For example, this simplifies creating widgets that implement the @Efl.Input.Clickable interface.
]]
methods {
- bind_to_theme @class {
+ bind_clickable_to_theme @static {
[[This will listen to the standard "click" events on a theme and emit the appropriate
- events through the @Efl.Ui.Clickable interface.
+ events through the @Efl.Input.Clickable interface.
Using these methods widgets do not need to listen to the theme signals. This class
does it and calls the correct clickable functions.
@@ -16,12 +16,12 @@ class @beta Efl.Ui.Clickable_Util {
]]
params {
object : Efl.Canvas.Layout; [[The object to listen on.]]
- clickable : Efl.Ui.Clickable; [[The object to call the clickable methods on.]]
+ clickable : Efl.Input.Clickable; [[The object to call the clickable methods on.]]
}
}
- bind_to_object @class {
+ bind_clickable_to_object @static {
[[This will listen to the standard "click" events on an object, and emit the appropriate
- events through the @Efl.Ui.Clickable interface.
+ events through the @Efl.Input.Clickable interface.
Using these methods widgets do not need to listen to the object events. This class
does it and calls the correct clickable functions.
@@ -30,7 +30,7 @@ class @beta Efl.Ui.Clickable_Util {
]]
params {
object : Efl.Input.Interface; [[The object to listen on.]]
- clickable : Efl.Ui.Clickable; [[The object to call the clickable methods on.]]
+ clickable : Efl.Input.Clickable; [[The object to call the clickable methods on.]]
}
}
}
diff --git a/src/lib/elementary/efl_ui_alert_popup.c b/src/lib/elementary/efl_ui_alert_popup.c
index e7eac4a955..c671754be9 100644
--- a/src/lib/elementary/efl_ui_alert_popup.c
+++ b/src/lib/elementary/efl_ui_alert_popup.c
@@ -41,7 +41,7 @@ _efl_ui_alert_popup_text_set(Eo *obj, Efl_Ui_Alert_Popup_Data *pd, const char *p
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
edje_object_message_signal_process(wd->resize_obj);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
}
}
else
@@ -154,15 +154,15 @@ _efl_ui_alert_popup_button_set(Eo *obj, Efl_Ui_Alert_Popup_Data *pd, Efl_Ui_Aler
switch (type)
{
case EFL_UI_ALERT_POPUP_BUTTON_POSITIVE:
- efl_event_callback_add(pd->button[type], EFL_UI_EVENT_CLICKED,
+ efl_event_callback_add(pd->button[type], EFL_INPUT_EVENT_CLICKED,
_positive_button_clicked_cb, obj);
break;
case EFL_UI_ALERT_POPUP_BUTTON_NEGATIVE:
- efl_event_callback_add(pd->button[type], EFL_UI_EVENT_CLICKED,
+ efl_event_callback_add(pd->button[type], EFL_INPUT_EVENT_CLICKED,
_negative_button_clicked_cb, obj);
break;
case EFL_UI_ALERT_POPUP_BUTTON_USER:
- efl_event_callback_add(pd->button[type], EFL_UI_EVENT_CLICKED,
+ efl_event_callback_add(pd->button[type], EFL_INPUT_EVENT_CLICKED,
_user_button_clicked_cb, obj);
break;
default:
@@ -228,7 +228,7 @@ _efl_ui_alert_popup_button_set(Eo *obj, Efl_Ui_Alert_Popup_Data *pd, Efl_Ui_Aler
edje_object_message_signal_process(wd->resize_obj);
}
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
}
EOLIAN static Eo *
diff --git a/src/lib/elementary/efl_ui_anchor_popup.c b/src/lib/elementary/efl_ui_anchor_popup.c
deleted file mode 100644
index ec0573be4c..0000000000
--- a/src/lib/elementary/efl_ui_anchor_popup.c
+++ /dev/null
@@ -1,351 +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);
-
- 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;
- //Add align calc only
- Eina_Bool needs_size_calc = ppd->needs_size_calc;
- elm_layout_sizing_eval(data);
- ppd->needs_size_calc = needs_size_calc;
-}
-
-static void
-_anchor_detach(Eo *obj)
-{
- EFL_UI_POPUP_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);
- }
-
- //Add align/anchor calc only
- Eina_Bool needs_size_calc = ppd->needs_size_calc;
- elm_layout_sizing_eval(obj);
- ppd->needs_size_calc = needs_size_calc;
-}
-
-EOLIAN static Efl_Object *
-_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)
-{
- EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
- /* When elm_layout_sizing_eval() is called, just flag is set instead of size
- * calculation.
- * The actual size calculation is done here when the object is rendered to
- * avoid duplicate size calculations. */
- if (ppd->needs_group_calc)
- {
- if (pd->anchor)
- ppd->needs_align_calc = EINA_FALSE;
-
- efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
-
- if (pd->anchor)
- _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"
diff --git a/src/lib/elementary/efl_ui_anchor_popup.eo b/src/lib/elementary/efl_ui_anchor_popup.eo
deleted file mode 100644
index 85b81c80e3..0000000000
--- a/src/lib/elementary/efl_ui_anchor_popup.eo
+++ /dev/null
@@ -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; }
- }
-}
diff --git a/src/lib/elementary/efl_ui_anchor_popup_private.h b/src/lib/elementary/efl_ui_anchor_popup_private.h
deleted file mode 100644
index db383d3fd9..0000000000
--- a/src/lib/elementary/efl_ui_anchor_popup_private.h
+++ /dev/null
@@ -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
diff --git a/src/lib/elementary/efl_ui_animation_view.c b/src/lib/elementary/efl_ui_animation_view.c
new file mode 100644
index 0000000000..7bcbbebcd7
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view.c
@@ -0,0 +1,1389 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_ACCESS_OBJECT_PROTECTED
+#define EFL_PART_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_animation_view_private.h"
+#include "efl_ui_animation_view_part.eo.h"
+#include "elm_part_helper.h"
+
+#define MY_CLASS EFL_UI_ANIMATION_VIEW_CLASS
+
+#define MY_CLASS_NAME "Efl_Ui_Animation_View"
+#define MY_CLASS_NAME_LEGACY "efl_ui_animation_view"
+
+#define GROW_SIZE 50
+#define QUEUE_SIZE 350
+#define T_SEGMENT_N 30
+#define C_SEGMENT_N 30
+
+
+static const char SIG_FOCUSED[] = "focused";
+static const char SIG_UNFOCUSED[] = "unfocused";
+static const char SIG_PLAY_START[] = "play,start";
+static const char SIG_PLAY_REPEAT[] = "play,repeat";
+static const char SIG_PLAY_DONE[] = "play,done";
+static const char SIG_PLAY_PAUSE[] = "play,pause";
+static const char SIG_PLAY_RESUME[] = "play,resume";
+static const char SIG_PLAY_STOP[] = "play,stop";
+static const char SIG_PLAY_UPDATE[] = "play,update";
+
+/* smart callbacks coming from Efl_Ui_Animation_View objects: */
+static const Evas_Smart_Cb_Description _smart_callbacks[] = {
+ {SIG_FOCUSED, ""},
+ {SIG_UNFOCUSED, ""},
+ {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
+ {SIG_PLAY_START, ""},
+ {SIG_PLAY_REPEAT, ""},
+ {SIG_PLAY_DONE, ""},
+ {SIG_PLAY_PAUSE, ""},
+ {SIG_PLAY_RESUME, ""},
+ {SIG_PLAY_STOP, ""},
+ {NULL, NULL}
+};
+
+typedef struct
+{
+ Eina_Stringshare *part;
+ Eo *obj;
+ Eo *proxy;
+ const Efl_VG *node;
+} Efl_Ui_Animation_View_Sub_Obj_Data;
+
+typedef struct
+{
+ float x1, x2;
+ float y;
+} Efl_Ui_Animation_View_Span_Data;
+
+typedef struct
+{
+ float x, y;
+} Efl_Ui_Animation_View_Point;
+
+static Eo *
+_proxy_create(Eo *source)
+{
+ Eo *proxy = efl_add(EFL_CANVAS_PROXY_CLASS, source);
+ if (!proxy) return NULL;
+
+ efl_gfx_fill_auto_set(proxy, EINA_TRUE);
+ efl_canvas_proxy_source_clip_set(proxy, EINA_FALSE);
+ efl_canvas_proxy_source_set(proxy, source);
+
+ efl_gfx_entity_visible_set(proxy, EINA_FALSE);
+ efl_gfx_entity_visible_set(source, EINA_FALSE);
+
+ return proxy;
+}
+
+static void
+_proxy_map_disable(Efl_Ui_Animation_View_Data *pd)
+{
+ Eina_List *l;
+ Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
+
+ EINA_LIST_FOREACH(pd->subs, l, sub_d)
+ {
+ if (!sub_d->proxy) continue;
+ if (efl_gfx_mapping_has(sub_d->proxy))
+ efl_gfx_mapping_reset(sub_d->proxy);
+
+ //TODO: remove this call
+ evas_object_map_enable_set(sub_d->proxy, EINA_FALSE);
+ }
+}
+
+static Efl_VG *
+_node_get(Efl_VG *node, const char *part)
+{
+ if (!node) return NULL;
+
+ if (!efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS)) return NULL;
+
+ char *name = efl_key_data_get(node, "_lot_node_name");
+
+ //Find the target recursiveldy
+ if (!name || strcmp(name, part))
+ {
+ Eina_Iterator *itr = efl_canvas_vg_container_children_get(node);
+ Efl_VG *child;
+ Efl_VG *ret;
+
+ EINA_ITERATOR_FOREACH(itr, child)
+ {
+ if (efl_isa(child, EFL_CANVAS_VG_CONTAINER_CLASS))
+ {
+ ret = _node_get(child, part);
+ if (ret) return ret;
+ }
+ }
+ return NULL;
+ }
+
+ //Find Shape
+ Eina_Iterator *itr = efl_canvas_vg_container_children_get(node);
+ Efl_VG *child;
+ const Efl_Gfx_Path_Command_Type *cmd;
+
+ EINA_ITERATOR_FOREACH(itr, child)
+ {
+ //Filter out unacceptable types
+ if (!efl_isa(child, EFL_CANVAS_VG_SHAPE_CLASS)) continue;
+ if (efl_gfx_shape_stroke_width_get(child) > 0) continue;
+ efl_gfx_path_get(child, &cmd, NULL);
+ if (!cmd) continue;
+ return child;
+ }
+ return NULL;
+}
+
+static Eina_Bool
+_part_draw(Efl_Ui_Animation_View_Sub_Obj_Data *sub_d, Eina_Position2D offset, Eina_Size2D tsize)
+{
+ const Efl_Gfx_Path_Command_Type *cmd, *tcmd;
+ const double *points;
+ int alpha, inarray_idx, inarray_size, i, pt_idx = 0, pt_cnt = 0;
+ double x, y;
+ Eina_Bezier bezier;
+ float t, min_y = 99999999, max_y = -1;
+ float inv_segment = (1 / (float) C_SEGMENT_N);
+ float u_segment, v_segment, x1_segment, x2_segment;
+ double begin_x = 0, begin_y = 0, end_x = 0, end_y = 0;
+ double ctrl[4];
+ Eina_Inarray *inarray;
+ Efl_Ui_Animation_View_Point *pt, *pt2;
+ Eo *target = sub_d->proxy;
+ Eina_Bool fast_path = EINA_TRUE;
+
+ efl_gfx_path_get(sub_d->node, &cmd, &points);
+ if (!cmd) return EINA_FALSE;
+
+ efl_gfx_entity_visible_set(target, EINA_TRUE);
+// efl_gfx_path_bounds_get(sub_d->node, &tbound);
+ efl_gfx_color_get(sub_d->node, NULL, NULL, NULL, &alpha);
+ efl_gfx_entity_size_set(target, tsize);
+
+ //TODO: Optimize it, scalable or not?
+ efl_gfx_entity_size_set(sub_d->obj, tsize);
+
+ //Fast Path? Shape outlines by consisted of straight lines.
+ tcmd = cmd;
+ if (*tcmd != EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO) fast_path = EINA_FALSE;
+ else
+ {
+ ++tcmd;
+ while (*tcmd == EFL_GFX_PATH_COMMAND_TYPE_LINE_TO)
+ {
+ ++tcmd;
+ if (++pt_cnt > 4)
+ {
+ fast_path = EINA_FALSE;
+ break;
+ }
+ }
+
+ if ((pt_cnt != 4) ||
+ (((*tcmd) != EFL_GFX_PATH_COMMAND_TYPE_END) && ((*tcmd) != EFL_GFX_PATH_COMMAND_TYPE_CLOSE)))
+ fast_path = EINA_FALSE;
+ }
+
+ pt_idx = 0;
+
+ //Fast Path: Rectangle Mapping
+ if (fast_path)
+ {
+ efl_gfx_mapping_point_count_set(target, pt_cnt);
+
+ //Point
+ efl_gfx_mapping_coord_absolute_set(target, 1, points[0] + offset.x, points[1] + offset.y, 0);
+ efl_gfx_mapping_coord_absolute_set(target, 2, points[2] + offset.x, points[3] + offset.y, 0);
+ efl_gfx_mapping_coord_absolute_set(target, 3, points[4] + offset.x, points[5] + offset.y, 0);
+ efl_gfx_mapping_coord_absolute_set(target, 0, points[6] + offset.x, points[7] + offset.y, 0);
+
+ //Color
+ efl_gfx_mapping_color_set(target, 0, alpha, alpha, alpha, alpha);
+ efl_gfx_mapping_color_set(target, 1, alpha, alpha, alpha, alpha);
+ efl_gfx_mapping_color_set(target, 2, alpha, alpha, alpha, alpha);
+ efl_gfx_mapping_color_set(target, 3, alpha, alpha, alpha, alpha);
+
+ //UV
+ efl_gfx_mapping_uv_set(target, 0, 0, 0);
+ efl_gfx_mapping_uv_set(target, 1, tsize.w, 0);
+ efl_gfx_mapping_uv_set(target, 2, tsize.w, tsize.h);
+ efl_gfx_mapping_uv_set(target, 3, 0, tsize.h);
+
+ return EINA_TRUE;
+ }
+
+ //Case 2. Arbitrary Geometry mapping
+ inarray = eina_inarray_new(sizeof(Efl_Ui_Animation_View_Point), GROW_SIZE);
+ if (!inarray) return EINA_FALSE;
+ eina_inarray_resize(inarray, QUEUE_SIZE);
+ inarray_size = QUEUE_SIZE;
+ inarray_idx = 0;
+
+ //end 0, move 1, line 2, cubic 3, close 4
+ while (*cmd != EFL_GFX_PATH_COMMAND_TYPE_END)
+ {
+ if (*cmd == EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO)
+ {
+ begin_x = points[pt_idx++] + offset.x;
+ begin_y = points[pt_idx++] + offset.y;
+ if (begin_y < min_y) min_y = begin_y;
+ if (begin_y > max_y) max_y = begin_y;
+ ++cmd;
+ continue;
+ }
+ else if (*cmd == EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO)
+ {
+
+ ctrl[0] = points[pt_idx++] + offset.x;
+ ctrl[1] = points[pt_idx++] + offset.y;
+ ctrl[2] = points[pt_idx++] + offset.x;
+ ctrl[3] = points[pt_idx++] + offset.y;
+ end_x = points[pt_idx++] + offset.x;
+ end_y = points[pt_idx++] + offset.y;
+
+ eina_bezier_values_set(&bezier,
+ begin_x, begin_y,
+ ctrl[0], ctrl[1], ctrl[2], ctrl[3],
+ end_x, end_y);
+
+ for (i = 0; i < C_SEGMENT_N; ++i)
+ {
+ if (inarray_idx >= inarray_size)
+ {
+ inarray_size += GROW_SIZE;
+ eina_inarray_grow(inarray, inarray_size);
+ }
+
+ t = inv_segment * (float) i;
+ eina_bezier_point_at(&bezier, t, &x, &y);
+ pt = eina_inarray_nth(inarray, inarray_idx);
+ pt->x = x;
+ pt->y = y;
+
+ if (y < min_y) min_y = y;
+ if (y > max_y) max_y = y;
+
+ ++inarray_idx;
+ }
+ }
+ else if (*cmd == EFL_GFX_PATH_COMMAND_TYPE_LINE_TO)
+ {
+ end_x = points[pt_idx++] + offset.x;
+ end_y = points[pt_idx++] + offset.y;
+
+ for (i = 0; i < C_SEGMENT_N; ++i)
+ {
+ if (inarray_idx >= inarray_size)
+ {
+ inarray_size += GROW_SIZE;
+ eina_inarray_grow(inarray, inarray_size);
+ }
+
+ t = inv_segment * (float) i;
+ pt = eina_inarray_nth(inarray, inarray_idx);
+ pt->x = begin_x + ((double) (end_x - begin_x)) * t;
+ pt->y = begin_y + ((double) (end_y - begin_y)) * t;
+ ++inarray_idx;
+ }
+ }
+
+ begin_x = end_x;
+ begin_y = end_y;
+
+ if (end_y < min_y) min_y = end_y;
+ if (end_y > max_y) max_y = end_y;
+
+ ++cmd;
+ }
+
+ if (inarray_idx >= inarray_size)
+ {
+ inarray_size += 1;
+ eina_inarray_grow(inarray, inarray_size);
+ }
+ pt = eina_inarray_nth(inarray, inarray_idx);
+ pt2 = eina_inarray_nth(inarray, 0);
+ pt->x = pt2->x;
+ pt->y = pt2->y;
+
+ float y_segment = (max_y - min_y) * inv_segment;
+ Efl_Ui_Animation_View_Span_Data spans[T_SEGMENT_N + 1];
+ float min_x, max_x;
+ float a, b;
+
+ y = min_y;
+
+ for (int i = 0; i <= T_SEGMENT_N; ++i)
+ {
+ min_x = 999999;
+ max_x = -1;
+
+ for (int j = 0; j < inarray_idx; ++j)
+ {
+ pt = eina_inarray_nth(inarray, j);
+ pt2 = pt + 1;
+
+ //Horizontal Line
+ if ((fabs(y - pt->y) < 0.5) &&
+ (fabs(pt->y - pt2->y) < 0.5))
+ {
+ if (pt->x < min_x) min_x = pt->x;
+ if (pt->x > max_x) max_x = pt->x;
+ if (pt2->x < min_x) min_x = pt2->x;
+ if (pt2->x > max_x) max_x = pt2->x;
+ continue;
+ }
+
+ //Out of Y range
+ if (((y < pt->y) && (y < pt2->y)) ||
+ ((y > pt->y) && (y > pt2->y)))
+ continue;
+
+ //Vertical Line
+ if (fabs(pt2->x - pt2->x) < 0.5)
+ x = pt->x;
+ //Diagonal Line
+ else
+ {
+ a = (pt2->y - pt->y) / (pt2->x - pt->x);
+ b = pt->y - (a * pt->x);
+ x = (y - b) / a;
+ }
+
+ if (x < min_x) min_x = x;
+ if (x > max_x) max_x = x;
+ }
+ spans[i].x1 = min_x;
+ spans[i].x2 = max_x;
+ spans[i].y = y;
+ y += y_segment;
+#if 0
+ static Eo *lines[T_SEGMENT_N + 1];
+ if (!lines[i]) lines[i] = evas_object_line_add(evas_object_evas_get(target));
+ evas_object_color_set(lines[i], 255, 255, 255, 255);
+ evas_object_resize(lines[i], 1000, 1000);
+ evas_object_line_xy_set(lines[i], spans[i].x1, spans[i].y, spans[i].x2, spans[i].y);
+ evas_object_show(lines[i]);
+#endif
+ }
+
+ u_segment = ((float) tsize.w) / ((float) T_SEGMENT_N);
+ v_segment = ((float) tsize.h) / ((float) T_SEGMENT_N);
+
+ Evas_Map *map = evas_map_new(T_SEGMENT_N * T_SEGMENT_N * 4);
+ pt_idx = 0;
+// efl_gfx_mapping_point_count_set(target, (4 * T_SEGMENT_N * T_SEGMENT_N));
+
+ for (int i = 0; i < T_SEGMENT_N; ++i)
+ {
+ x1_segment = (spans[i].x2 - spans[i].x1) / ((float) T_SEGMENT_N);
+ x2_segment = (spans[i + 1].x2 - spans[i + 1].x1) / ((float) T_SEGMENT_N);
+
+ for (int j = 0; j < T_SEGMENT_N; ++j)
+ {
+#if 0
+ //Point
+ efl_gfx_mapping_coord_absolute_set(target, pt_idx + 0, spans[i].x1 + ((float) j) * x1_segment, spans[i].y, 0);
+ efl_gfx_mapping_coord_absolute_set(target, pt_idx + 1, spans[i].x1 + ((float) j + 1) * x1_segment, spans[i].y, 0);
+ efl_gfx_mapping_coord_absolute_set(target, pt_idx + 2, spans[i + 1].x1 + ((float) j + 1) * x2_segment, spans[i + 1].y, 0);
+ efl_gfx_mapping_coord_absolute_set(target, pt_idx + 3, spans[i + 1].x1 + ((float) j) * x2_segment, spans[i + 1].y, 0);
+
+ //UV
+ efl_gfx_mapping_uv_set(target, pt_idx + 0, ((float) j) * u_segment, ((float) i) * v_segment);
+ efl_gfx_mapping_uv_set(target, pt_idx + 1, ((float) j + 1) * u_segment, ((float) i) * v_segment);
+ efl_gfx_mapping_uv_set(target, pt_idx + 2, ((float) j + 1) * u_segment, ((float) i + 1) * v_segment);
+ efl_gfx_mapping_uv_set(target, pt_idx + 3, ((float) j) * u_segment, ((float) i + 1) * v_segment);
+
+ //Color
+ efl_gfx_mapping_color_set(target, pt_idx + 0, alpha, alpha, alpha, alpha);
+ efl_gfx_mapping_color_set(target, pt_idx + 1, alpha, alpha, alpha, alpha);
+ efl_gfx_mapping_color_set(target, pt_idx + 2, alpha, alpha, alpha, alpha);
+ efl_gfx_mapping_color_set(target, pt_idx + 3, alpha, alpha, alpha, alpha);
+#endif
+ evas_map_point_coord_set(map, pt_idx + 0, spans[i].x1 + ((float) j) * x1_segment, spans[i].y, 0);
+ evas_map_point_coord_set(map, pt_idx + 1, spans[i].x1 + ((float) j + 1) * x1_segment, spans[i].y, 0);
+ evas_map_point_coord_set(map, pt_idx + 2, spans[i + 1].x1 + ((float) j + 1) * x2_segment, spans[i + 1].y, 0);
+ evas_map_point_coord_set(map, pt_idx + 3, spans[i + 1].x1 + ((float) j) * x2_segment, spans[i + 1].y, 0);
+
+ evas_map_point_image_uv_set(map, pt_idx + 0, ((float) j) * u_segment, ((float) i) * v_segment);
+ evas_map_point_image_uv_set(map, pt_idx + 1, ((float) j + 1) * u_segment, ((float) i) * v_segment);
+ evas_map_point_image_uv_set(map, pt_idx + 2, ((float) j + 1) * u_segment, ((float) i + 1) * v_segment);
+ evas_map_point_image_uv_set(map, pt_idx + 3, ((float) j) * u_segment, ((float) i + 1) * v_segment);
+
+ evas_map_point_color_set(map, pt_idx + 0, alpha, alpha, alpha, alpha);
+ evas_map_point_color_set(map, pt_idx + 1, alpha, alpha, alpha, alpha);
+ evas_map_point_color_set(map, pt_idx + 2, alpha, alpha, alpha, alpha);
+ evas_map_point_color_set(map, pt_idx + 3, alpha, alpha, alpha, alpha);
+
+ pt_idx += 4;
+ }
+ }
+ evas_object_map_enable_set(target, EINA_TRUE);
+ evas_object_map_set(target, map);
+
+ evas_map_free(map);
+ eina_inarray_free(inarray);
+
+ return EINA_TRUE;
+}
+
+static void
+_update_part_contents(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ if (!pd->subs) return;
+
+ //TODO: Update to current frame's node tree immediately.
+
+ Efl_VG *root = evas_object_vg_root_node_get(pd->vg);
+ if (!root) return;
+
+ Eina_List *l;
+ Eina_Position2D pos = efl_gfx_entity_position_get(pd->vg);
+ Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
+ Eina_Size2D tsize = efl_gfx_entity_size_get(obj);
+
+ EINA_LIST_FOREACH(pd->subs, l, sub_d)
+ {
+ if (!sub_d->node)
+ sub_d->node = _node_get(root, sub_d->part);
+
+ if (sub_d->node)
+ _part_draw(sub_d, pos, tsize);
+ else
+ ERR("part(%s) is invalid in Efl_Ui_Animation_View(%p)", sub_d->part, obj);
+ }
+}
+
+static void
+_frame_set_facade(Eo *obj, Efl_Ui_Animation_View_Data *pd, int frame)
+{
+ int pframe = evas_object_vg_animated_frame_get(pd->vg);
+ evas_object_vg_animated_frame_set(pd->vg, frame);
+ if (pframe != frame) _update_part_contents(obj, pd);
+}
+
+static void
+_eo_unparent_helper(Eo *child, Eo *parent)
+{
+ if (efl_parent_get(child) == parent)
+ efl_parent_set(child, evas_object_evas_get(parent));
+}
+
+static void
+_on_sub_object_size_hint_change(void *data,
+ Evas *e EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ if (!efl_alive_get(data)) return;
+ ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
+ efl_canvas_group_change(data);
+ //TODO: Update part contents
+}
+
+static void
+_sizing_eval(Eo *obj, void *data)
+{
+ Efl_Ui_Animation_View_Data *pd = data;
+ if (!efl_file_loaded_get(obj)) return;
+
+ double hw,hh;
+ efl_gfx_hint_weight_get(obj, &hw, &hh);
+
+ Eina_Size2D size = efl_canvas_vg_object_default_size_get(pd->vg);
+
+ Eina_Size2D min = {-1, -1};
+ if (hw == 0) min.w = size.w;
+ if (hh == 0) min.h = size.h;
+
+ efl_gfx_hint_size_min_set(obj, min);
+}
+
+static void
+_size_hint_event_cb(void *data, const Efl_Event *event)
+{
+ _sizing_eval(event->object, data);
+}
+
+static void
+_transit_go_facade(Eo* obj, Efl_Ui_Animation_View_Data *pd)
+{
+ pd->repeat_times = 0;
+ if (pd->play_back)
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
+ else
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
+ evas_object_smart_callback_call(obj, SIG_PLAY_START, NULL);
+ if (pd->transit) elm_transit_go(pd->transit);
+}
+
+static Eina_Bool
+_visible_check(Eo *obj)
+{
+ if (!efl_gfx_entity_visible_get(obj)) return EINA_FALSE;
+
+ //TODO: Check Smart parents visibilities?
+
+ Eina_Size2D size = efl_gfx_entity_size_get(obj);
+ if (size.w == 0 || size.h == 0) return EINA_FALSE;
+
+ Evas_Coord output_w, output_h;
+ evas_output_size_get(evas_object_evas_get(obj), &output_w, &output_h);
+
+ Eina_Position2D pos = efl_gfx_entity_position_get(obj);
+
+ //Outside viewport
+ if ((pos.x + size.w < 0) || (pos.x > output_w) ||
+ (pos.y + size.h < 0) || (pos.y > output_h))
+ return EINA_FALSE;
+
+ //Inside viewport
+ return EINA_TRUE;
+}
+
+static void
+_auto_play(Eo *obj, Efl_Ui_Animation_View_Data *pd, Eina_Bool vis)
+{
+ if (!pd->auto_play || !pd->transit) return;
+
+ //Resume Animation
+ if (vis)
+ {
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PAUSE && pd->auto_play_pause)
+ {
+ elm_transit_paused_set(pd->transit, EINA_FALSE);
+ if (pd->play_back)
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
+ else
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
+ pd->auto_play_pause = EINA_FALSE;
+ evas_object_smart_callback_call(obj, SIG_PLAY_RESUME, NULL);
+ }
+ }
+ //Pause Animation
+ else
+ {
+ if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) ||
+ (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK))
+ {
+ elm_transit_paused_set(pd->transit, EINA_TRUE);
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PAUSE;
+ pd->auto_play_pause = EINA_TRUE;
+ evas_object_smart_callback_call(obj, SIG_PLAY_PAUSE, NULL);
+ }
+ }
+}
+
+static void
+_transit_del_cb(Elm_Transit_Effect *effect, Elm_Transit *transit)
+{
+ Eo *obj = (Eo *) effect;
+ EFL_UI_ANIMATION_VIEW_DATA_GET(obj, pd);
+ if (!pd) return;
+
+ if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY && pd->progress == 1) ||
+ (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK && pd->progress == 0))
+ evas_object_smart_callback_call(obj, SIG_PLAY_DONE, NULL);
+
+ if (pd->transit != transit) return;
+
+ Efl_Ui_Animation_View_State prev_state = pd->state;
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_STOP;
+ pd->transit = NULL;
+ pd->auto_play_pause = EINA_FALSE;
+
+ if (prev_state != EFL_UI_ANIMATION_VIEW_STATE_STOP)
+ {
+ evas_object_smart_callback_call(obj, SIG_PLAY_STOP, NULL);
+ pd->progress = 0;
+ }
+}
+
+static void
+_transit_cb(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
+{
+ Eo *obj = (Eo *) effect;
+ EFL_UI_ANIMATION_VIEW_DATA_GET(obj, pd);
+
+ if (!pd || !pd->vg)
+ {
+ ERR("Vector Object is removed in wrong way!, Efl_Ui_Animation_View = %p", obj);
+ elm_transit_del(transit);
+ return;
+ }
+
+ if (pd->play_back)
+ {
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
+ progress = 1 - progress;
+ }
+ else pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
+
+ pd->progress = progress;
+ int minframe = (pd->frame_cnt - 1) * pd->min_progress;
+ int maxframe = (pd->frame_cnt - 1) * pd->max_progress;
+
+ int update_frame = (int)((maxframe - minframe) * progress) + minframe;
+ int current_frame = evas_object_vg_animated_frame_get(pd->vg);
+ _frame_set_facade(obj, pd, update_frame);
+
+ if (pd->auto_repeat)
+ {
+ int repeat_times = elm_transit_current_repeat_times_get(pd->transit);
+ if (pd->repeat_times != repeat_times)
+ {
+ evas_object_smart_callback_call(obj, SIG_PLAY_REPEAT, NULL);
+ pd->repeat_times = repeat_times;
+ }
+ }
+
+ //transit_cb is always called with a progress value 0 ~ 1.
+ //SIG_PLAY_UPDATE callback is called only when there is a real change.
+ if (update_frame != current_frame)
+ evas_object_smart_callback_call(obj, SIG_PLAY_UPDATE, NULL);
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Animation_View_Data *priv)
+{
+ efl_canvas_group_add(efl_super(obj, MY_CLASS));
+ elm_widget_sub_object_parent_add(obj);
+
+ // Create vg to render vector animation
+ Eo *vg = evas_object_vg_add(evas_object_evas_get(obj));
+ elm_widget_resize_object_set(obj, vg);
+ efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _size_hint_event_cb, priv);
+
+ priv->vg = vg;
+ priv->speed = 1;
+ priv->frame_duration = 0;
+ priv->min_progress = 0.0;
+ priv->max_progress = 1.0;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
+{
+ if (pd->transit)
+ {
+ Elm_Transit *transit = pd->transit;
+ pd->transit = NULL; //Skip perform transit_del_cb()
+ elm_transit_del(transit);
+ }
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_NOT_READY;
+
+ efl_canvas_group_del(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_object_destructor(Eo *obj,
+ Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static Eo *
+_efl_ui_animation_view_efl_object_constructor(Eo *obj,
+ Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
+ evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
+
+ return obj;
+}
+
+static void
+_update_frame_duration(Efl_Ui_Animation_View_Data *pd)
+{
+ int frame_count = evas_object_vg_animated_frame_count_get(pd->vg);
+ int min_frame = (frame_count - 1) * pd->min_progress;
+ int max_frame = (frame_count - 1) * pd->max_progress;
+ double frame_rate = round((double)frame_count / evas_object_vg_animated_frame_duration_get(pd->vg, 0, 0));
+
+ pd->frame_duration = (double)(max_frame - min_frame) / frame_rate;
+ if (pd->transit)
+ elm_transit_duration_set(pd->transit, pd->frame_duration * (1/pd->speed));
+}
+
+static Eina_Bool
+_ready_play(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ pd->auto_play_pause = EINA_FALSE;
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_STOP;
+
+ if (pd->transit) elm_transit_del(pd->transit);
+
+ pd->frame_cnt = (double) evas_object_vg_animated_frame_count_get(pd->vg);
+ pd->frame_duration = evas_object_vg_animated_frame_duration_get(pd->vg, 0, 0);
+ _frame_set_facade(obj, pd, 0);
+
+ if (pd->frame_duration > 0)
+ {
+ Elm_Transit *transit = elm_transit_add();
+ elm_transit_object_add(transit, pd->vg);
+ if (pd->auto_repeat) elm_transit_repeat_times_set(transit, -1);
+ elm_transit_effect_add(transit, _transit_cb, obj, _transit_del_cb);
+ elm_transit_progress_value_set(transit, pd->progress);
+ elm_transit_objects_final_state_keep_set(transit, EINA_TRUE);
+ pd->transit = transit;
+ if (pd->min_progress != 0.0 || pd->max_progress != 1.0)
+ _update_frame_duration(pd);
+ else
+ elm_transit_duration_set(transit, pd->frame_duration * (1/pd->speed));
+
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_file_unload(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_NOT_READY;
+ pd->frame_cnt = 0;
+ pd->frame_duration = 0;
+ if (pd->transit) elm_transit_del(pd->transit);
+
+ //Remove all part exising contents
+ Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
+ Eo *content;
+ Eina_List *l, *ll;
+
+ EINA_LIST_FOREACH_SAFE(pd->subs, l, ll, sub_d)
+ {
+ content = sub_d->obj;
+
+ /* sub_d will die in _widget_sub_object_del */
+ if (!_elm_widget_sub_object_redirect_to_top(obj, content))
+ {
+ ERR("could not remove sub object %p from %p", content, obj);
+ continue;
+ }
+ _eo_unparent_helper(content, obj);
+ }
+}
+
+EOLIAN static Eina_Error
+_efl_ui_animation_view_efl_file_load(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ Eina_Error err;
+ Eina_Bool ret;
+ const char *file;
+ const char *key;
+
+ if (efl_file_loaded_get(obj)) return 0;
+
+ err = efl_file_load(efl_super(obj, MY_CLASS));
+ if (err) return err;
+
+ file = efl_file_get(obj);
+ key = efl_file_key_get(obj);
+ ret = efl_file_simple_load(pd->vg, file, key);
+ if (!ret)
+ {
+ efl_file_unload(obj);
+ return eina_error_get();
+ }
+
+ pd->progress = 0;
+
+ _sizing_eval(obj, pd);
+
+ if (!_ready_play(obj, pd)) return 1;
+
+ if (pd->auto_play)
+ {
+ _transit_go_facade(obj, pd);
+
+ if (!_visible_check(obj))
+ {
+ elm_transit_paused_set(pd->transit, EINA_TRUE);
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PAUSE;
+ pd->auto_play_pause = EINA_TRUE;
+ evas_object_smart_callback_call(obj, SIG_PLAY_PAUSE, NULL);
+ }
+ }
+ return 0;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_gfx_entity_position_set(Eo *obj,
+ Efl_Ui_Animation_View_Data *pd,
+ Eina_Position2D pos)
+{
+ if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
+ return;
+
+ efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
+
+ Eina_Bool vis = _visible_check(obj);
+ if (!vis) _proxy_map_disable(pd);
+ _auto_play(obj, pd, vis);
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_gfx_entity_size_set(Eo *obj,
+ Efl_Ui_Animation_View_Data *pd,
+ Eina_Size2D size)
+{
+ if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, size.w, size.h))
+ return;
+
+ efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), size);
+
+ _sizing_eval(obj, pd);
+
+ _auto_play(obj, pd, _visible_check(obj));
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_gfx_entity_visible_set(Eo *obj,
+ Efl_Ui_Animation_View_Data *pd,
+ Eina_Bool vis)
+{
+ if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_VISIBLE, 0, vis))
+ return;
+
+ efl_gfx_entity_visible_set(efl_super(obj, MY_CLASS), vis);
+
+ vis = _visible_check(obj);
+ if (!vis) _proxy_map_disable(pd);
+ _auto_play(obj, pd, vis);
+}
+
+EOLIAN static void
+_efl_ui_animation_view_efl_gfx_view_view_size_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_Animation_View_Data *pd,
+ Eina_Size2D size)
+{
+ Eina_Rect viewbox;
+ viewbox.x = viewbox.y =0;
+ viewbox.w = size.w;
+ viewbox.h = size.h;
+
+ efl_canvas_vg_object_viewbox_set(pd->vg, viewbox);
+}
+
+EOLIAN Eina_Size2D
+_efl_ui_animation_view_efl_gfx_view_view_size_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_Animation_View_Data *pd)
+{
+ Eina_Rect viewbox = efl_canvas_vg_object_viewbox_get(pd->vg);
+
+ return EINA_SIZE2D(viewbox.w, viewbox.h);
+}
+
+EOLIAN static void
+_efl_ui_animation_view_auto_repeat_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, Eina_Bool auto_repeat)
+{
+ if (pd->auto_repeat == auto_repeat) return;
+ pd->auto_repeat = auto_repeat;
+ if (pd->transit)
+ {
+ if (auto_repeat) elm_transit_repeat_times_set(pd->transit, -1);
+ else elm_transit_repeat_times_set(pd->transit, 0);
+ }
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_auto_repeat_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->auto_repeat;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_auto_play_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd,
+ Eina_Bool auto_play)
+{
+ pd->auto_play = auto_play;
+ if (!auto_play) pd->auto_play_pause = EINA_FALSE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_auto_play_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->auto_play;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_play(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) return EINA_FALSE;
+
+ Eina_Bool rewind = EINA_FALSE;
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK) rewind = EINA_TRUE;
+
+ pd->play_back = EINA_FALSE;
+ pd->auto_play_pause = EINA_FALSE;
+
+ if (!efl_file_loaded_get(obj)) return EINA_FALSE;
+ if (!pd->transit && !_ready_play(obj, pd)) return EINA_FALSE;
+
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_STOP)
+ _transit_go_facade(obj, pd);
+ else if (rewind)
+ elm_transit_progress_value_set(pd->transit, pd->progress);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_stop(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ if (!pd->transit) return EINA_FALSE;
+
+ if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_NOT_READY) ||
+ (pd->state == EFL_UI_ANIMATION_VIEW_STATE_STOP))
+ return EINA_FALSE;
+
+ _frame_set_facade(obj, pd, 0);
+
+ pd->progress = 0;
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_STOP;
+ evas_object_smart_callback_call(obj, SIG_PLAY_STOP, NULL);
+ elm_transit_del(pd->transit);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_pause(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ if (!pd->transit) return EINA_FALSE;
+
+ if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) ||
+ (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK))
+ {
+ elm_transit_paused_set(pd->transit, EINA_TRUE);
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PAUSE;
+ pd->auto_play_pause = EINA_FALSE;
+ evas_object_smart_callback_call(obj, SIG_PLAY_PAUSE, NULL);
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_resume(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ if (!pd->transit) return EINA_FALSE;
+
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PAUSE)
+ {
+ elm_transit_paused_set(pd->transit, EINA_FALSE);
+ if (pd->play_back)
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
+ else
+ pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
+ pd->auto_play_pause = EINA_FALSE;
+
+ evas_object_smart_callback_call(obj, SIG_PLAY_RESUME, NULL);
+
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_play_back(Eo *obj, Efl_Ui_Animation_View_Data *pd)
+{
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK) return EINA_FALSE;
+
+ Eina_Bool rewind = EINA_FALSE;
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) rewind = EINA_TRUE;
+
+ pd->play_back = EINA_TRUE;
+ pd->auto_play_pause = EINA_FALSE;
+
+ if (!efl_file_loaded_get(obj)) return EINA_FALSE;
+ if (!pd->transit && !_ready_play(obj, pd)) return EINA_FALSE;
+
+ if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_STOP)
+ {
+ if (pd->progress == 0) pd->progress = 1.0;
+ _transit_go_facade(obj, pd);
+ }
+ else if (rewind)
+ elm_transit_progress_value_set(pd->transit, 1 - pd->progress);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_speed_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double speed)
+{
+ if (speed <= 0) return EINA_FALSE;
+ pd->speed = speed;
+
+ if (pd->transit)
+ elm_transit_duration_set(pd->transit, pd->frame_duration * (1/pd->speed));
+
+ return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_progress_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double progress)
+{
+ if (progress < 0) progress = 0;
+ else if (progress > 1) progress = 1;
+ if (pd->progress == progress) return;
+
+ pd->progress = progress;
+
+ if (pd->frame_cnt > 0)
+ _frame_set_facade(obj, pd, (int) ((pd->frame_cnt - 1) * progress));
+
+ if (pd->transit)
+ {
+ if (pd->play_back)
+ elm_transit_progress_value_set(pd->transit, 1 - progress);
+ else
+ elm_transit_progress_value_set(pd->transit, progress);
+ }
+}
+
+EOLIAN static double
+_efl_ui_animation_view_progress_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->progress;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_frame_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, int frame_num)
+{
+ efl_ui_animation_view_progress_set(obj, (double) frame_num / (double) (evas_object_vg_animated_frame_count_get(pd->vg) - 1));
+}
+
+EOLIAN static int
+_efl_ui_animation_view_frame_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ double progress = (pd->progress * (pd->max_progress - pd->min_progress)) + pd->min_progress;
+ return (int) ((double) (evas_object_vg_animated_frame_count_get(pd->vg) - 1) * progress);
+}
+
+EOLIAN static double
+_efl_ui_animation_view_speed_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->speed;
+}
+
+EOLIAN static double
+_efl_ui_animation_view_duration_time_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->frame_duration;
+}
+
+EOLIAN static Eina_Size2D
+_efl_ui_animation_view_default_view_size_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
+{
+ return efl_canvas_vg_object_default_size_get(pd->vg);
+}
+
+EOLIAN static Efl_Ui_Animation_View_State
+_efl_ui_animation_view_state_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->state;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_is_playing_back(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->play_back;
+}
+
+EOLIAN static int
+_efl_ui_animation_view_frame_count_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return efl_gfx_frame_controller_frame_count_get(pd->vg);
+}
+
+EOLIAN static void
+_efl_ui_animation_view_min_progress_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double min_progress)
+{
+ if (min_progress < 0.0 || min_progress > 1.0 || min_progress > pd->max_progress) return;
+
+ pd->min_progress = min_progress;
+ _update_frame_duration(pd);
+}
+
+EOLIAN static double
+_efl_ui_animation_view_min_progress_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->min_progress;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_max_progress_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double max_progress)
+{
+ if (max_progress < 0.0 || max_progress > 1.0 || max_progress < pd->min_progress) return;
+
+ pd->max_progress = max_progress;
+ _update_frame_duration(pd);
+}
+
+EOLIAN static double
+_efl_ui_animation_view_max_progress_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->max_progress;
+}
+
+EOLIAN static void
+_efl_ui_animation_view_min_frame_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, int min_frame)
+{
+ int frame_count = evas_object_vg_animated_frame_count_get(pd->vg);
+ if (min_frame < 0) min_frame = 0;
+ else
+ {
+ int max_frame = (frame_count - 1) * pd->max_progress;
+ if (min_frame > max_frame) min_frame = max_frame;
+ }
+
+ pd->min_progress = (double)min_frame / (double)(frame_count - 1);
+ _update_frame_duration(pd);
+}
+
+EOLIAN static int
+_efl_ui_animation_view_min_frame_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->min_progress * (evas_object_vg_animated_frame_count_get(pd->vg) - 1);
+}
+
+EOLIAN static void
+_efl_ui_animation_view_max_frame_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, int max_frame)
+{
+ int frame_count = evas_object_vg_animated_frame_count_get(pd->vg);
+ if (max_frame > frame_count - 1) max_frame = frame_count - 1;
+ else
+ {
+ int min_frame = (frame_count - 1) * pd->min_progress;
+ if (min_frame > max_frame) max_frame = min_frame;
+ }
+
+ pd->max_progress = (double)max_frame / (double)(frame_count - 1);
+ _update_frame_duration(pd);
+}
+
+EOLIAN static int
+_efl_ui_animation_view_max_frame_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
+{
+ return pd->max_progress * (evas_object_vg_animated_frame_count_get(pd->vg) - 1);
+}
+
+EOLIAN static Efl_Object *
+_efl_ui_animation_view_efl_part_part_get(const Eo* obj, Efl_Ui_Animation_View_Data *pd EINA_UNUSED, const char *part)
+{
+ return ELM_PART_IMPLEMENT(EFL_UI_ANIMATION_VIEW_PART_CLASS, obj, part);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_efl_ui_widget_widget_sub_object_add(Eo *obj, Efl_Ui_Animation_View_Data *pd EINA_UNUSED, Evas_Object *sobj)
+{
+ Eina_Bool int_ret = EINA_FALSE;
+
+ if (evas_object_data_get(sobj, "elm-parent") == obj) return EINA_TRUE;
+
+ int_ret = elm_widget_sub_object_add(efl_super(obj, MY_CLASS), sobj);
+ if (!int_ret) return EINA_FALSE;
+
+ evas_object_event_callback_add
+ (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _on_sub_object_size_hint_change, obj);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_animation_view_efl_ui_widget_widget_sub_object_del(Eo *obj, Efl_Ui_Animation_View_Data *pd, Evas_Object *sobj)
+{
+ Eina_List *l;
+ Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
+ Eina_Bool int_ret = EINA_FALSE;
+
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
+
+ evas_object_event_callback_del_full
+ (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _on_sub_object_size_hint_change, obj);
+
+ int_ret = elm_widget_sub_object_del(efl_super(obj, MY_CLASS), sobj);
+ if (!int_ret) return EINA_FALSE;
+// if (pd->destructed_is) return EINA_TRUE;
+
+ EINA_LIST_FOREACH(pd->subs, l, sub_d)
+ {
+ if (sub_d->obj != sobj) continue;
+ pd->subs = eina_list_remove_list(pd->subs, l);
+ if (sub_d->proxy) efl_del(sub_d->proxy);
+ eina_stringshare_del(sub_d->part);
+ free(sub_d);
+ break;
+ }
+
+ // No need to resize object during destruction
+ if (wd->resize_obj && efl_alive_get(obj))
+ efl_canvas_group_change(obj);
+
+ return EINA_TRUE;
+}
+
+EAPI Elm_Animation_View*
+elm_animation_view_add(Evas_Object *parent)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
+ return elm_legacy_add(MY_CLASS, parent);
+}
+
+EAPI Eina_Bool
+elm_animation_view_file_set(Elm_Animation_View *obj, const char *file, const char *key)
+{
+ return efl_file_simple_load(obj, file, key);
+}
+
+EAPI Elm_Animation_View_State
+elm_animation_view_state_get(Elm_Animation_View *obj)
+{
+ return efl_ui_animation_view_state_get(obj);
+}
+
+static Eina_Bool
+_efl_ui_animation_view_content_set(Eo *obj, Efl_Ui_Animation_View_Data *pd, const char *part, Efl_Gfx_Entity *content)
+{
+ Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
+ Eina_List *l;
+
+ if (!efl_file_loaded_get(obj)) return EINA_FALSE;
+
+ EINA_LIST_FOREACH(pd->subs, l, sub_d)
+ {
+ if (!strcmp(part, sub_d->part))
+ {
+ if (content == sub_d->obj) goto end;
+ if (efl_alive_get(sub_d->obj))
+ {
+ if (sub_d->proxy) efl_del(sub_d->proxy);
+ _eo_unparent_helper(sub_d->obj, obj);
+ efl_del(sub_d->obj);
+ }
+ break;
+ }
+ else if (content == sub_d->obj)
+ {
+ pd->subs = eina_list_remove_list(pd->subs, l);
+ eina_stringshare_del(sub_d->part);
+ if (sub_d->proxy) efl_del(sub_d->proxy);
+ free(sub_d);
+ _elm_widget_sub_object_redirect_to_top(obj, content);
+ break;
+ }
+ }
+
+ if (content)
+ {
+ if (!elm_widget_sub_object_add(obj, content)) return EINA_FALSE;
+
+ sub_d = ELM_NEW(Efl_Ui_Animation_View_Sub_Obj_Data);
+ if (!sub_d)
+ {
+ ERR("failed to allocate memory!");
+ _elm_widget_sub_object_redirect_to_top(obj, content);
+ return EINA_FALSE;
+ }
+ sub_d->part = eina_stringshare_add(part);
+ sub_d->obj = content;
+ sub_d->proxy = _proxy_create(sub_d->obj);
+ pd->subs = eina_list_append(pd->subs, sub_d);
+ efl_parent_set(content, obj);
+ }
+
+ efl_canvas_group_change(obj);
+
+ _update_part_contents(obj, pd);
+
+end:
+ return EINA_TRUE;
+}
+
+static Efl_Gfx_Entity *
+_efl_ui_animation_view_content_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, const char *part)
+{
+ const Eina_List *l;
+ Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
+
+ EINA_LIST_FOREACH(pd->subs, l, sub_d)
+ {
+ if (strcmp(part, sub_d->part)) continue;
+ return sub_d->obj;
+ }
+
+ return NULL;
+}
+
+static Efl_Gfx_Entity *
+_efl_ui_animation_view_content_unset(Eo *obj, Efl_Ui_Animation_View_Data *pd, const char *part)
+{
+ Efl_Ui_Animation_View_Sub_Obj_Data *sub_d;
+ Eina_List *l;
+ Eo *content;
+
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+
+ EINA_LIST_FOREACH(pd->subs, l, sub_d)
+ {
+ if (!strcmp(part, sub_d->part))
+ {
+ if (!sub_d->obj)
+ {
+ ERR("Sub Object Data doens't have valid object, Something wrong....");
+ return NULL;
+ }
+
+ content = sub_d->obj;
+
+ /* sub_d will die in _widget_sub_object_del */
+ if (!_elm_widget_sub_object_redirect_to_top(obj, content))
+ {
+ ERR("could not remove sub object %p from %p", content, obj);
+ return NULL;
+ }
+ _eo_unparent_helper(content, obj);
+
+ return content;
+ }
+ }
+
+ return NULL;
+}
+
+#undef GROW_SIZE
+#undef QUEUE_SIZE
+#undef T_SEGMENT_N
+#undef C_SEGMENT_N
+
+
+/* Efl.Part begin */
+ELM_PART_OVERRIDE_CONTENT_SET(efl_ui_animation_view, EFL_UI_ANIMATION_VIEW, Efl_Ui_Animation_View_Data)
+ELM_PART_OVERRIDE_CONTENT_GET(efl_ui_animation_view, EFL_UI_ANIMATION_VIEW, Efl_Ui_Animation_View_Data)
+ELM_PART_OVERRIDE_CONTENT_UNSET(efl_ui_animation_view, EFL_UI_ANIMATION_VIEW, Efl_Ui_Animation_View_Data)
+#include "efl_ui_animation_view_part.eo.c"
+/* Efl.Part end */
+
+/* Internal EO APIs and hidden overrides */
+
+#define EFL_UI_ANIMATION_VIEW_EXTRA_OPS \
+ EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_animation_view)
+
+#include "efl_ui_animation_view_eo.legacy.c"
+#include "efl_ui_animation_view.eo.c"
diff --git a/src/lib/elementary/efl_ui_animation_view.eo b/src/lib/elementary/efl_ui_animation_view.eo
new file mode 100644
index 0000000000..2511db247e
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view.eo
@@ -0,0 +1,285 @@
+
+enum Efl.Ui.Animation_View_State
+{
+ [[State of animation view]]
+ not_ready, [[Animation is not ready to play. (Probably, it didn't file set yet or failed to read file.]]
+ play, [[Animation is on playing. see @Efl.Ui.Animation_View.play]]
+ play_back, [[Animation is on playing back (rewinding). see @Efl.Ui.Animation_View.play_back]]
+ pause, [[Animation has been paused. To continue animation, call @Efl.Ui.Animation_View.resume. see @Efl.Ui.Animation_View.pause]]
+ stop [[Animation view successfully loaded a file then readied for playing. Otherwise after finished animation or stopped forcely by request. see @Efl.Ui.Animation_View.stop]]
+}
+
+class @beta Efl.Ui.Animation_View extends Efl.Ui.Widget implements Efl.Gfx.View, Efl.File, Efl.Part
+{
+ [[Elementary Animation view class.
+ Animation view is designed to show and play animation of
+ vector graphics based content. It hides all efl_canvas_vg details
+ but just open an API to read vector data from file. Also, it implements
+ details of animation control methods of Vector.
+
+ Vector data could contain static or animatable vector elements including
+ animation infomation. Currently approved vector data file format is svg, json and eet.
+ Only json(known for Lottie file as well) and eet could contains animation infomation,
+ currently Animation_View is supporting.
+ ]]
+ event_prefix: efl_ui_animation_view;
+ methods {
+ @property auto_play {
+ [[Animation will be started automatically when it's possible.
+
+ If @.auto_play is $true, animation will be started when it's readied.
+ The condition of $auto play is when animation view opened file successfully,
+ yet to play it plus when the object is visible.
+ If animation view is disabled, invisible,
+ it turns to pause state then resume animation when it's visible again.
+
+ $true Enable auto play mode, disable otherwise.
+
+ Warning: This auto play will be only affected to the next animation source.
+ So must be called before setting animation file.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ auto_play: bool; [[Auto play mode, Default value is $false]]
+ }
+ }
+ @property auto_repeat {
+ [[Turn on/off animation looping.
+
+ If @.auto_repeat is $true, it repeats animation when animation frame is reached to
+ end. This auto repeat mode is valid to both play and play_back cases.
+
+ $true Enable auto play mode, disable otherwise.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ auto_repeat: bool; [[Loop mode, Defalut is $false.]]
+ }
+ }
+ @property speed {
+ [[Control animation speed.
+
+ Control animation speed by multiplying $speed value. If you want to play
+ animation double-time faster, you can give $speed 2. If you want to play
+ animation double-time slower, you can give $speed 0.5.
+
+ $true when it's successful. $false otherwise.
+
+ Warning: speed must be greater than zero.
+ ]]
+ set {
+ return: bool;
+ }
+ get {
+ }
+ values {
+ speed: double; [[ Speed factor. Default value is 1.0]]
+ }
+ }
+ @property duration_time {
+ [[Get the duration of animation in seconds.
+
+ This API returns total duration time of current animation in the seconds.
+ If current animation source isn't animatable, it returns zero.
+ ]]
+ get {
+ }
+ values {
+ frame_duration: double; [[duration time in the seconds]]
+ }
+ }
+ @property progress {
+ [[Set current progress position of animation view object.
+
+ When you required to jump on a certain frame instantly,
+ you can change current position by using this API.
+
+ Warning: The range of progress is 0 ~ 1.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ progress: double; [[Progress position. Value must be 0 ~ 1.]]
+ }
+ }
+ @property frame {
+ [[Number of current frame.
+
+ Ranges from 0 to @.frame_count - 1.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ frame_num: int; [[Current frame number.]]
+ }
+ }
+ play {
+ [[Play animation one time instantly when it's available.
+
+ If current keyframe is on a certain position by playing back, this will
+ play forward from there.
+
+ Warning: Play request will be ignored if animation source is not set yet or
+ animation is paused state or it's already on playing.
+ ]]
+
+ return: bool; [[$true when it's successful. $false otherwise.]]
+ }
+ play_back {
+ [[Play back animation one time instantly when it's available.
+
+ If current keyframe is on a certain position by playing, this will
+ play backward from there.
+
+ Warning: Play back request will be ignored if animation source is not set yet or
+ animation is paused state or it's already on playing back.
+ ]]
+
+ return: bool; [[$true when it's successful. $false otherwise.]]
+ }
+ pause {
+ [[Pause current animation instantly.
+
+ Once animation is paused, animation view must get resume to play continue again.
+
+ Warning: Animation must be on playing or playing back status.
+ ]]
+
+ return: bool; [[$true when it's successful. $false otherwise.]]
+ }
+ resume {
+ [[Resume paused animation to continue animation.
+
+ Warning: This resume must be called on animation paused status.
+ ]]
+
+ return: bool; [[$true when it's successful. $false otherwise.]]
+ }
+ stop {
+ [[Stop playing animation.
+
+ Stop animation instatly regardless of it's status and reset to
+ show first frame of animation. Even though current animation is paused,
+ the animation status will be stopped.
+ ]]
+
+ return: bool; [[$true when it's successful. $false otherwise.]]
+ }
+ @property default_view_size {
+ [[The default view size that specified from vector resource.
+ ]]
+ get {
+ }
+ values {
+ size: Eina.Size2D;
+ }
+ }
+ @property state {
+ [[Current animation view state.
+ see @Efl.Ui.Animation_View_State
+ ]]
+ get{
+ }
+ values {
+ state: Efl.Ui.Animation_View_State; [[Current animation view state]]
+ }
+ }
+ is_playing_back {
+ [[Returns the status whether current animation is on playing forward or backward.
+ warning: If animation view is not on playing, it will return $false.
+ ]]
+ return: bool; [[$true, if animation on playing back, $false otherwise.]]
+ }
+ @property frame_count {
+ [[The index of end frame of the animation view, if it's animated.
+ note : frame number starts with 0.
+ ]]
+ get {
+ }
+ values {
+ frame_count: int; [[The number of frames. 0, if it's not animated.]]
+ }
+ }
+ @property min_progress {
+ [[The start progress of the play.
+ Default value is 0.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ min_progress: double; [[The minimum progress. Value must be 0 ~ 1.]]
+ }
+ }
+ @property max_progress {
+ [[The last progress of the play.
+ Default value is 1.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ max_progress: double; [[The maximum progress. Value must be 0 ~ 1.]]
+ }
+ }
+ @property min_frame {
+ [[The start frame of the play.
+ Default value is 0.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ min_frame: int; [[The minimum frame for play. Value must be 0 ~ @.max_frame]]
+ }
+ }
+ @property max_frame {
+ [[The last frame of the play.
+ Default value is @.frame_count - 1
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ max_frame: int; [[The maximum frame for play. Value must be @.min_frame ~ (@.frame_count - 1)]]
+ }
+ }
+
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ Efl.File.load;
+ Efl.File.unload;
+ Efl.Gfx.Entity.visible { set; }
+ Efl.Gfx.Entity.position { set; }
+ Efl.Gfx.Entity.size { set; }
+ Efl.Gfx.View.view_size { set; get; }
+ Efl.Part.part_get;
+ Efl.Ui.Widget.widget_sub_object_add;
+ Efl.Ui.Widget.widget_sub_object_del;
+ }
+ events {
+ play,start: void; [[Called when animation is just started]]
+ play,repeat: void; [[Called when animation is just repeated]]
+ play,done: void; [[Called when animation is just finished]]
+ play,pause: void; [[Called when animation is just paused]]
+ play,resume: void; [[Called when animation is just resumed]]
+ play,stop: void; [[Called when animation is just stopped]]
+ play,update: void; [[Called when animation is just updated]]
+ }
+}
diff --git a/src/lib/elementary/efl_ui_animation_view.h b/src/lib/elementary/efl_ui_animation_view.h
new file mode 100644
index 0000000000..9241791bf4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view.h
@@ -0,0 +1,33 @@
+/**
+ * @defgroup Elm_Animation_View Animation View
+ * @ingroup Elementary
+ *
+ * Animation_View widget is designed to show and play animation of
+ * vector graphics based content. It hides all efl_canvas_vg details
+ * but just open an API to read vector data from file. Also, it implements
+ * details of animation control methods of Vector.
+ *
+ * Vector data could contain static or animatable vector elements including
+ * animation infomation. Currently approved vector data file format is svg, json and eet.
+ * Only json(known for Lottie file as well) and eet could contains animation infomation,
+ * currently Animation_View is supporting.
+ *
+ * This widget emits the following signals, besides the ones sent from Animation View.
+ * @li "play,start": animation is just started.
+ * @li "play,repeat": animation is just repeated.
+ * @li "play,done": animation is just finished.
+ * @li "play,pause": animation is just paused.
+ * @li "play,resume": animation is just resumed.
+ * @li "play,stop": animation is just stopped.
+ * @li "play,update": animation is updated to the next frame.
+ *
+ */
+/**
+ * @ingroup Elm_Animation_View
+ */
+#ifndef EFL_NOLEGACY_API_SUPPORT
+#include "efl_ui_animation_view_legacy.h"
+#endif
+/**
+ * @}
+ */
diff --git a/src/lib/elementary/efl_ui_animation_view_eo.legacy.c b/src/lib/elementary/efl_ui_animation_view_eo.legacy.c
new file mode 100644
index 0000000000..87ed3232d1
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view_eo.legacy.c
@@ -0,0 +1,162 @@
+
+EAPI void
+elm_animation_view_auto_play_set(Efl_Ui_Animation_View *obj, Eina_Bool auto_play)
+{
+ efl_ui_animation_view_auto_play_set(obj, auto_play);
+}
+
+EAPI Eina_Bool
+elm_animation_view_auto_play_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_auto_play_get(obj);
+}
+
+EAPI void
+elm_animation_view_auto_repeat_set(Efl_Ui_Animation_View *obj, Eina_Bool auto_repeat)
+{
+ efl_ui_animation_view_auto_repeat_set(obj, auto_repeat);
+}
+
+EAPI Eina_Bool
+elm_animation_view_auto_repeat_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_auto_repeat_get(obj);
+}
+
+EAPI Eina_Bool
+elm_animation_view_speed_set(Efl_Ui_Animation_View *obj, double speed)
+{
+ return efl_ui_animation_view_speed_set(obj, speed);
+}
+
+EAPI double
+elm_animation_view_speed_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_speed_get(obj);
+}
+
+EAPI double
+elm_animation_view_duration_time_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_duration_time_get(obj);
+}
+
+EAPI void
+elm_animation_view_progress_set(Efl_Ui_Animation_View *obj, double progress)
+{
+ efl_ui_animation_view_progress_set(obj, progress);
+}
+
+EAPI double
+elm_animation_view_progress_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_progress_get(obj);
+}
+
+EAPI void
+elm_animation_view_frame_set(Efl_Ui_Animation_View *obj, int frame_num)
+{
+ efl_ui_animation_view_frame_set(obj, frame_num);
+}
+
+EAPI int
+elm_animation_view_frame_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_frame_get(obj);
+}
+
+EAPI Eina_Bool
+elm_animation_view_play(Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_play(obj);
+}
+
+EAPI Eina_Bool
+elm_animation_view_play_back(Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_play_back(obj);
+}
+
+EAPI Eina_Bool
+elm_animation_view_pause(Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_pause(obj);
+}
+
+EAPI Eina_Bool
+elm_animation_view_resume(Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_resume(obj);
+}
+
+EAPI Eina_Bool
+elm_animation_view_stop(Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_stop(obj);
+}
+
+EAPI Eina_Size2D
+elm_animation_view_default_size_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_default_view_size_get(obj);
+}
+
+EAPI Eina_Bool
+elm_animation_view_is_playing_back(Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_is_playing_back(obj);
+}
+
+EAPI int
+elm_animation_view_frame_count_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_frame_count_get(obj);
+}
+
+EAPI void
+elm_animation_view_min_progress_set(Efl_Ui_Animation_View *obj, double min_progress)
+{
+ efl_ui_animation_view_min_progress_set(obj, min_progress);
+}
+
+EAPI double
+elm_animation_view_min_progress_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_min_progress_get(obj);
+}
+
+EAPI void
+elm_animation_view_max_progress_set(Efl_Ui_Animation_View *obj, double max_progress)
+{
+ efl_ui_animation_view_max_progress_set(obj, max_progress);
+}
+
+EAPI double
+elm_animation_view_max_progress_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_max_progress_get(obj);
+}
+
+EAPI void
+elm_animation_view_min_frame_set(Efl_Ui_Animation_View *obj, int min_frame)
+{
+ efl_ui_animation_view_min_frame_set(obj, min_frame);
+}
+
+EAPI int
+elm_animation_view_min_frame_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_min_frame_get(obj);
+}
+
+EAPI void
+elm_animation_view_max_frame_set(Efl_Ui_Animation_View *obj, int max_frame)
+{
+ efl_ui_animation_view_max_frame_set(obj, max_frame);
+}
+
+EAPI int
+elm_animation_view_max_frame_get(const Efl_Ui_Animation_View *obj)
+{
+ return efl_ui_animation_view_max_frame_get(obj);
+}
diff --git a/src/lib/elementary/efl_ui_animation_view_eo.legacy.h b/src/lib/elementary/efl_ui_animation_view_eo.legacy.h
new file mode 100644
index 0000000000..78dd2f1d5d
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view_eo.legacy.h
@@ -0,0 +1,517 @@
+#ifndef _EFL_UI_ANIMATION_VIEW_EO_LEGACY_H_
+#define _EFL_UI_ANIMATION_VIEW_EO_LEGACY_H_
+
+#ifndef _ELM_ANIMATION_VIEW_EO_CLASS_TYPE
+#define _ELM_ANIMATION_VIEW_EO_CLASS_TYPE
+
+typedef Eo Elm_Animation_View;
+
+#endif
+
+#ifndef _ELM_ANIMATION_VIEW_EO_TYPES
+#define _ELM_ANIMATION_VIEW_EO_TYPES
+
+/**
+ * @brief Defines the state of animation view
+ *
+ * @ingroup Elm_Animation_View
+ */
+typedef enum
+{
+ ELM_ANIMATION_VIEW_STATE_NOT_READY = 0, /**< Animation is not ready to
+ * play. (Probably, it didn't file
+ * set yet or failed to read file.
+ *
+ * @since 1.23 */
+ ELM_ANIMATION_VIEW_STATE_PLAY, /**< Animation is on playing. see
+ * @ref elm_animation_view_play
+ *
+ * @since 1.23 */
+ ELM_ANIMATION_VIEW_STATE_PLAY_BACK, /**< Animation is on playing back
+ * (rewinding). see
+ * @ref elm_animation_view_play_back
+ *
+ * @since 1.23 */
+ ELM_ANIMATION_VIEW_STATE_PAUSE, /**< Animation has been paused. To continue
+ * animation, call
+ * @ref elm_animation_view_resume. see
+ * @ref elm_animation_view_pause
+ *
+ * @since 1.23 */
+ ELM_ANIMATION_VIEW_STATE_STOP /**< Animation view successfully loaded a
+ * file then readied for playing. Otherwise
+ * after finished animation or stopped
+ * forcely by request. see
+ * @ref elm_animation_view_stop
+ *
+ * @since 1.23 */
+} Elm_Animation_View_State;
+
+
+#endif
+
+/**
+ * @brief Animation will be started automatically when it's possible.
+ *
+ * If @ref elm_animation_view_auto_play_get is @c true, animation will be
+ * started when it's readied. The condition of @c auto play is when animation
+ * view opened file successfully, yet to play it plus when the object is
+ * visible. If animation view is disabled, invisible, it turns to pause state
+ * then resume animation when it's visible again.
+ *
+ * @warning This auto play will be only affected to the next animation source.
+ * So must be called before setting animation file
+ *
+ * Set auto play mode of an animation view object. @c true Enable auto play
+ * mode, disable otherwise
+ *
+ * @param[in] obj The object.
+ * @param[in] auto_play Auto play mode, Default value is @c false
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_auto_play_set(Elm_Animation_View *obj, Eina_Bool auto_play);
+
+/**
+ * @brief Animation will be started automatically when it's possible.
+ *
+ * If @ref elm_animation_view_auto_play_get is @c true, animation will be
+ * started when it's readied. The condition of @c auto play is when animation
+ * view opened file successfully, yet to play it plus when the object is
+ * visible. If animation view is disabled, invisible, it turns to pause state
+ * then resume animation when it's visible again.
+ *
+ * @warning This auto play will be only affected to the next animation source.
+ * So must be called before setting animation file
+ *
+ * Returns auto play mode of an animation view object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return Auto play mode, Default value is @c false
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_auto_play_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief Turn on/off animation looping.
+ *
+ * If @ref elm_animation_view_auto_repeat_get is @c true, it repeats animation
+ * when animation frame is reached to end. This auto repeat mode is valid to
+ * both play and play_back cases.
+ *
+ * Enable loop mode if @c true, disable otherwise.
+ *
+ * @param[in] obj The object.
+ * @param[in] auto_repeat Loop mode, Defalut is @c false.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_auto_repeat_set(Elm_Animation_View *obj, Eina_Bool auto_repeat);
+
+/**
+ * @brief Turn on/off animation looping.
+ *
+ * If @ref elm_animation_view_auto_repeat_get is @c true, it repeats animation
+ * when animation frame is reached to end. This auto repeat mode is valid to
+ * both play and play_back cases.
+ *
+ * Returns auto repeat mode of an animation view object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return Loop mode, Defalut is @c false.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_auto_repeat_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief Control animation speed.
+ *
+ * Control animation speed by multiplying @c speed value. If you want to play
+ * animation double-time faster, you can give @c speed 2. If you want to play
+ * animation double-time slower, you can give @c speed 0.5.
+ *
+ * @warning speed must be greater than zero.
+ *
+ * @param[in] obj The object.
+ * @param[in] speed Speed factor. Default value is 1.0
+ *
+ * @return @c true when it's successful. @c false otherwise.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_speed_set(Elm_Animation_View *obj, double speed);
+
+/**
+ * @brief Control animation speed.
+ *
+ * Control animation speed by multiplying @c speed value. If you want to play
+ * animation double-time faster, you can give @c speed 2. If you want to play
+ * animation double-time slower, you can give @c speed 0.5.
+ *
+ * @warning speed must be greater than zero.
+ *
+ * Returns current animation speed of an animation view object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return Speed factor. Default value is 1.0
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI double elm_animation_view_speed_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief Get the duration of animation in seconds.
+ *
+ * This API returns total duration time of current animation in the seconds. If
+ * current animation source isn't animatable, it returns zero.
+ *
+ * Returns current duration of an animation in seconds.
+ *
+ * @param[in] obj The object.
+ *
+ * @return duration time in the seconds
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI double elm_animation_view_duration_time_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief Set current progress position of animation view object.
+ *
+ * When you required to jump on a certain frame instantly, you can change
+ * current position by using this API.
+ *
+ * @warning The range of progress is 0 ~ 1.
+ *
+ * Set the current progress position of an animation view object.
+ *
+ * @param[in] obj The object.
+ * @param[in] progress Progress position. Value must be 0 ~ 1.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_progress_set(Elm_Animation_View *obj, double progress);
+
+/**
+ * @brief Set current progress position of animation view object.
+ *
+ * When you required to jump on a certain frame instantly, you can change
+ * current position by using this API.
+ *
+ * @warning The range of progress is 0 ~ 1.
+ *
+ * Returns current progress position of an animation view object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return Progress position. Value must be 0 ~ 1.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI double elm_animation_view_progress_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief Number of current frame.
+ *
+ * Ranges from 0 to @ref elm_animation_view_frame_count_get - 1.
+ *
+ * Set the current frame of an animation view object.
+ *
+ * @param[in] obj The object.
+ * @param[in] frame_num Current frame number.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_frame_set(Elm_Animation_View *obj, int frame_num);
+
+/**
+ * @brief Number of current frame.
+ *
+ * Ranges from 0 to @ref elm_animation_view_frame_count_get - 1.
+ *
+ * Returns the current frame of an animation view object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return Current frame number.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI int elm_animation_view_frame_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief Play animation one time instantly when it's available.
+ *
+ * If current keyframe is on a certain position by playing back, this will play
+ * forward from there.
+ *
+ * @warning Play request will be ignored if animation source is not set yet or
+ * animation is paused state or it's already on playing.
+ *
+ * @param[in] obj The object.
+ *
+ * @return @c true when it's successful. @c false otherwise.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_play(Elm_Animation_View *obj);
+
+/**
+ * @brief Play back animation one time instantly when it's available.
+ *
+ * If current keyframe is on a certain position by playing, this will play
+ * backward from there.
+ *
+ * @warning Play back request will be ignored if animation source is not set
+ * yet or animation is paused state or it's already on playing back.
+ *
+ * @param[in] obj The object.
+ *
+ * @return @c true when it's successful. @c false otherwise.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_play_back(Elm_Animation_View *obj);
+
+/**
+ * @brief Pause current animation instantly.
+ *
+ * Once animation is paused, animation view must get resume to play continue
+ * again.
+ *
+ * @warning Animation must be on playing or playing back status.
+ *
+ * @param[in] obj The object.
+ *
+ * @return @c true when it's successful. @c false otherwise.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_pause(Elm_Animation_View *obj);
+
+/**
+ * @brief Resume paused animation to continue animation.
+ *
+ * @warning This resume must be called on animation paused status.
+ *
+ * @param[in] obj The object.
+ *
+ * @return @c true when it's successful. @c false otherwise.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_resume(Elm_Animation_View *obj);
+
+/**
+ * @brief Stop playing animation.
+ *
+ * Stop animation instatly regardless of it's status and reset to show first
+ * frame of animation. Even though current animation is paused, the animation
+ * status will be stopped.
+ *
+ * @param[in] obj The object.
+ *
+ * @return @c true when it's successful. @c false otherwise.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_stop(Elm_Animation_View *obj);
+
+/** Get the default view size that specified from vector resource.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Size2D elm_animation_view_default_size_get(const Elm_Animation_View *obj);
+
+
+/**
+ * @brief Returns the status whether current animation is on playing forward or
+ * backward. warning: If animation view is not on playing, it will return
+ * @c false.
+ *
+ * @param[in] obj The object.
+ *
+ * @return @c true, if animation on playing back, @c false otherwise.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI Eina_Bool elm_animation_view_is_playing_back(Elm_Animation_View *obj);
+
+/**
+ * @brief Get the index of end frame of the animation view, if it's animated.
+ * note : frame number starts with 0.
+ *
+ * @param[in] obj The object.
+ *
+ * @return The number of frames. 0, if it's not animated.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI int elm_animation_view_frame_count_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief The start progress of the play. Default value is 0.
+ *
+ * Set start progress of an animation object.
+ *
+ * @param[in] obj The object.
+ * @param[in] min_progress The minimum progress. Value must be 0 ~ 1.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_min_progress_set(Elm_Animation_View *obj, double min_progress);
+
+/**
+ * @brief The start progress of the play. Default value is 0.
+ *
+ * Returns start progress of an animation object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return The minimum progress. Value must be 0 ~ 1.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI double elm_animation_view_min_progress_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief The last progress of the play. Default value is 1.
+ *
+ * Set last progress of an animation object.
+ *
+ * @param[in] obj The object.
+ * @param[in] max_progress The maximum progress. Value must be 0 ~ 1.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_max_progress_set(Elm_Animation_View *obj, double max_progress);
+
+/**
+ * @brief The last progress of the play. Default value is 1.
+ *
+ * Returns last progress of an animation object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return The maximum progress. Value must be 0 ~ 1.
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI double elm_animation_view_max_progress_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief The start frame of the play. Default value is 0.
+ *
+ * Set minimum frame of an animation object.
+ *
+ * @param[in] obj The object.
+ * @param[in] min_frame The minimum frame for play. Value must be 0 ~
+ * @ref elm_animation_view_max_frame_get
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_min_frame_set(Elm_Animation_View *obj, int min_frame);
+
+/**
+ * @brief The start frame of the play. Default value is 0.
+ *
+ * Returns minimum frame of an animation object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return The minimum frame for play. Value must be 0 ~
+ * @ref elm_animation_view_max_frame_get
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI int elm_animation_view_min_frame_get(const Elm_Animation_View *obj);
+
+/**
+ * @brief The last frame of the play. Default value is
+ * @ref elm_animation_view_frame_count_get - 1
+ *
+ * Set maximum frame of an animation object.
+ *
+ * @param[in] obj The object.
+ * @param[in] max_frame The maximum frame for play. Value must be
+ * @ref elm_animation_view_min_frame_get ~ (@ref elm_animation_view_frame_count_get - 1)
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI void elm_animation_view_max_frame_set(Elm_Animation_View *obj, int max_frame);
+
+/**
+ * @brief The last frame of the play. Default value is
+ * @ref elm_animation_view_frame_count_get - 1
+ *
+ * Returns maximum frame of an animation object.
+ *
+ * @param[in] obj The object.
+ *
+ * @return The maximum frame for play. Value must be
+ * @ref elm_animation_view_min_frame_get ~ (@ref elm_animation_view_frame_count_get - 1)
+ *
+ * @since 1.23
+ *
+ * @ingroup Elm_Animation_View
+ */
+EAPI int elm_animation_view_max_frame_get(const Elm_Animation_View *obj);
+
+#endif
diff --git a/src/lib/elementary/efl_ui_animation_view_legacy.h b/src/lib/elementary/efl_ui_animation_view_legacy.h
new file mode 100644
index 0000000000..95054168c5
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view_legacy.h
@@ -0,0 +1,49 @@
+
+#include "efl_ui_animation_view_eo.legacy.h"
+
+/**
+ * Add a new animation view widget to the parent's canvas
+ *
+ * @param parent The parent object
+ * @return The new animation view object or @c NULL if it failed to create.
+ *
+ * @ingroup Elm_Animation_View
+ *
+ * @since 1.23
+ */
+EAPI Elm_Animation_View *elm_animation_view_add(Evas_Object *parent);
+
+/**
+ *
+ * Set the source file from where an vector object must fetch the real
+ * vector data (it may be one of json, svg, eet files).
+ *
+ * If the file supports multiple data stored in it (as Eet files do),
+ * you can specify the key to be used as the index of the vector in
+ * this file.
+ *
+ * @param[in] file The vector file path.
+ * @param[in] key The vector key in @p file (if its an Eet one), or @c
+NULL, otherwise.
+ *
+ * @return @c EINA_TRUE if it's succeed to read file, @c EINA_FALSE otherwise.
+ *
+ * @ingroup Elm_Animation_View
+ *
+ * @since 1.23
+*/
+EAPI Eina_Bool elm_animation_view_file_set(Elm_Animation_View *obj, const char *file, const char *key);
+
+/**
+ * @brief Get current animation view state.
+ *
+ * @return Current animation view state
+ *
+ * @see Elm_Animation_View_State
+ *
+ * @ingroup Elm_Animation_View
+ *
+ * @since 1.23
+ */
+EAPI Elm_Animation_View_State elm_animation_view_state_get(Elm_Animation_View *obj);
+
diff --git a/src/lib/elementary/efl_ui_animation_view_part.eo b/src/lib/elementary/efl_ui_animation_view_part.eo
new file mode 100644
index 0000000000..de3abafc0f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view_part.eo
@@ -0,0 +1,9 @@
+class @beta Efl.Ui.Animation_View_Part extends Efl.Ui.Widget_Part implements Efl.Content
+{
+ [[Efl UI Animation_View internal part class]]
+ data: null;
+ implements {
+ Efl.Content.content { set; get; }
+ Efl.Content.content_unset;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_animation_view_private.h b/src/lib/elementary/efl_ui_animation_view_private.h
new file mode 100644
index 0000000000..b5bcd56ff2
--- /dev/null
+++ b/src/lib/elementary/efl_ui_animation_view_private.h
@@ -0,0 +1,42 @@
+#ifndef EFL_UI_ANIMATION_VIEW_PRIVATE_H
+#define EFL_UI_ANIMATION_VIEW_PRIVATE_H
+
+#include "Elementary.h"
+#include "efl_ui_animation_view.eo.h"
+
+typedef struct _Efl_Ui_Animation_View_Data Efl_Ui_Animation_View_Data;
+
+struct _Efl_Ui_Animation_View_Data
+{
+ Eo* vg; //Evas_Object_Vg
+ Efl_Ui_Animation_View_State state;
+ Elm_Transit *transit;
+ Eina_Stringshare *file;
+ double speed;
+ double progress;
+ double frame_cnt;
+ int repeat_times;
+ double frame_duration;
+ double min_progress;
+ double max_progress;
+ Eina_List *subs;
+
+ Eina_Bool play_back : 1;
+ Eina_Bool auto_play : 1;
+ Eina_Bool auto_play_pause: 1;
+ Eina_Bool auto_repeat : 1;
+};
+
+#define EFL_UI_ANIMATION_VIEW_DATA_GET(o, sd) \
+ Efl_Ui_Animation_View_Data * sd = efl_data_scope_safe_get(o, EFL_UI_ANIMATION_VIEW_CLASS)
+
+#define EFL_UI_ANIMATION_VIEW_DATA_GET_OR_RETURN(o, ptr) \
+ EFL_UI_ANIMATION_VIEW_DATA_GET(o, ptr); \
+ if (EINA_UNLIKELY(!ptr)) \
+ { \
+ ERR("No widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ return; \
+ }
+
+#endif
diff --git a/src/lib/elementary/efl_ui_bg_legacy_eo.c b/src/lib/elementary/efl_ui_bg_legacy_eo.c
index 9cd23ff42f..ea7bffcb8d 100644
--- a/src/lib/elementary/efl_ui_bg_legacy_eo.c
+++ b/src/lib/elementary/efl_ui_bg_legacy_eo.c
@@ -32,4 +32,4 @@ static const Efl_Class_Description _efl_ui_bg_legacy_class_desc = {
NULL
};
-EFL_DEFINE_CLASS(efl_ui_bg_legacy_class_get, &_efl_ui_bg_legacy_class_desc, EFL_UI_BG_CLASS, EFL_UI_LEGACY_INTERFACE, NULL);
+EFL_DEFINE_CLASS(efl_ui_bg_legacy_class_get, &_efl_ui_bg_legacy_class_desc, EFL_UI_BG_CLASS, ELM_LAYOUT_MIXIN, EFL_UI_LEGACY_INTERFACE, NULL);
diff --git a/src/lib/elementary/efl_ui_box.c b/src/lib/elementary/efl_ui_box.c
index 9db283ba6f..58b77f1d40 100644
--- a/src/lib/elementary/efl_ui_box.c
+++ b/src/lib/elementary/efl_ui_box.c
@@ -131,6 +131,7 @@ _efl_ui_box_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Data *pd)
EOLIAN static void
_efl_ui_box_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED)
{
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
efl_pack_layout_update(obj);
}
diff --git a/src/lib/elementary/efl_ui_box.eo b/src/lib/elementary/efl_ui_box.eo
index 008fb6d46c..d55f67f3cc 100644
--- a/src/lib/elementary/efl_ui_box.eo
+++ b/src/lib/elementary/efl_ui_box.eo
@@ -60,5 +60,7 @@ class Efl.Ui.Box extends Efl.Ui.Widget implements Efl.Pack_Linear, Efl.Pack_Layo
Efl.Pack_Linear.pack_index_get;
Efl.Pack_Layout.layout_update;
Efl.Pack_Layout.layout_request;
+ @empty Efl.Ui.L10n.l10n_text { get; set; }
+ @empty Efl.Ui.I18n.language { get; set; }
}
}
diff --git a/src/lib/elementary/efl_ui_box_flow.c b/src/lib/elementary/efl_ui_box_flow.c
index 82917f090d..2ad1fd7cdd 100644
--- a/src/lib/elementary/efl_ui_box_flow.c
+++ b/src/lib/elementary/efl_ui_box_flow.c
@@ -193,6 +193,7 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd
cross_min_sum += row->cross_space;
cross_weight_sum += row->cross_weight;
+ item_last += row->item_count;
if (bd->homogeneous)
continue;
@@ -205,7 +206,6 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd
calc_size = box_size;
inlist = NULL;
- item_last += row->item_count;
for (; i < item_last; i++)
{
double denom;
@@ -246,6 +246,7 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd
else if (EINA_DBL_EQ(row->weight_sum, 0))
{
row->cur_pos += (box_size - row->min_sum) * box_calc[axis].align;
+ i += row->item_count;
}
}
diff --git a/src/lib/elementary/efl_ui_button.c b/src/lib/elementary/efl_ui_button.c
index 6694a91f4a..f71fb3e0ad 100644
--- a/src/lib/elementary/efl_ui_button.c
+++ b/src/lib/elementary/efl_ui_button.c
@@ -6,7 +6,7 @@
#define EFL_ACCESS_OBJECT_PROTECTED
#define ELM_LAYOUT_PROTECTED
#define EFL_PART_PROTECTED
-#define EFL_UI_CLICKABLE_PROTECTED
+#define EFL_INPUT_CLICKABLE_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"
@@ -77,25 +77,13 @@ _activate(Evas_Object *obj)
evas_object_smart_callback_call(obj, "clicked", NULL);
else
{
- efl_ui_clickable_press(obj, 1);
- efl_ui_clickable_unpress(obj, 1);
+ efl_input_clickable_press(obj, 1);
+ efl_input_clickable_unpress(obj, 1);
}
}
}
}
-EOLIAN static void
-_efl_ui_button_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Button_Data *_pd EINA_UNUSED)
-{
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- Evas_Coord minw = -1, minh = -1;
-
- elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- edje_object_size_min_restricted_calc
- (wd->resize_obj, &minw, &minh, minw, minh);
- evas_object_size_hint_min_set(obj, minw, minh);
-}
-
EOLIAN static Eina_Bool
_efl_ui_button_efl_ui_widget_on_access_activate(Eo *obj, Efl_Ui_Button_Data *_pd EINA_UNUSED, Efl_Ui_Activate act)
{
@@ -107,8 +95,8 @@ _efl_ui_button_efl_ui_widget_on_access_activate(Eo *obj, Efl_Ui_Button_Data *_pd
evas_object_smart_callback_call(obj, "clicked", NULL);
else
{
- efl_ui_clickable_press(obj, 1);
- efl_ui_clickable_unpress(obj, 1);
+ efl_input_clickable_press(obj, 1);
+ efl_input_clickable_unpress(obj, 1);
}
if (elm_widget_is_legacy(obj))
@@ -259,7 +247,7 @@ _efl_ui_button_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Button_Data *_pd EINA_
edje_object_signal_callback_add
(wd->resize_obj, "efl,action,unpress", "*",
_on_unpressed_signal, obj);
- efl_ui_clickable_util_bind_to_theme(wd->resize_obj, obj);
+ efl_ui_action_connector_bind_clickable_to_theme(wd->resize_obj, obj);
}
_elm_access_object_register(obj, wd->resize_obj);
@@ -390,7 +378,6 @@ ELM_LAYOUT_CONTENT_ALIASES_IMPLEMENT(MY_CLASS_PFX)
#define EFL_UI_BUTTON_EXTRA_OPS \
ELM_LAYOUT_CONTENT_ALIASES_OPS(MY_CLASS_PFX), \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_button), \
EFL_CANVAS_GROUP_ADD_OPS(efl_ui_button)
#include "efl_ui_button.eo.c"
@@ -422,7 +409,7 @@ _icon_signal_emit(Evas_Object *obj)
elm_layout_signal_emit(obj, buf, "elm");
edje_object_message_signal_process(elm_layout_edje_get(obj));
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
}
/* FIXME: replicated from elm_layout just because button's icon spot
diff --git a/src/lib/elementary/efl_ui_button.eo b/src/lib/elementary/efl_ui_button.eo
index 449d501276..794ed9b04a 100644
--- a/src/lib/elementary/efl_ui_button.eo
+++ b/src/lib/elementary/efl_ui_button.eo
@@ -1,4 +1,4 @@
-class Efl.Ui.Button extends Efl.Ui.Layout_Base implements Efl.Ui.Clickable, Efl.Ui.Autorepeat,
+class Efl.Ui.Button extends Efl.Ui.Layout_Base implements Efl.Input.Clickable, Efl.Ui.Autorepeat,
Efl.Text, Efl.Content,
Efl.Access.Widget.Action
{
diff --git a/src/lib/elementary/efl_ui_button_legacy_eo.c b/src/lib/elementary/efl_ui_button_legacy_eo.c
index 0fcd13af64..81d3735872 100644
--- a/src/lib/elementary/efl_ui_button_legacy_eo.c
+++ b/src/lib/elementary/efl_ui_button_legacy_eo.c
@@ -44,4 +44,4 @@ static const Efl_Class_Description _efl_ui_button_legacy_class_desc = {
NULL
};
-EFL_DEFINE_CLASS(efl_ui_button_legacy_class_get, &_efl_ui_button_legacy_class_desc, EFL_UI_BUTTON_CLASS, EFL_UI_LEGACY_INTERFACE, NULL);
+EFL_DEFINE_CLASS(efl_ui_button_legacy_class_get, &_efl_ui_button_legacy_class_desc, EFL_UI_BUTTON_CLASS, ELM_LAYOUT_MIXIN, EFL_UI_LEGACY_INTERFACE, NULL);
diff --git a/src/lib/elementary/efl_ui_caching_factory.c b/src/lib/elementary/efl_ui_caching_factory.c
index bea7a3360c..33a44a013d 100644
--- a/src/lib/elementary/efl_ui_caching_factory.c
+++ b/src/lib/elementary/efl_ui_caching_factory.c
@@ -2,11 +2,14 @@
# include <config.h>
#endif
+#define EFL_UI_FACTORY_PROTECTED
+
#include <Elementary.h>
#include "elm_priv.h"
typedef struct _Efl_Ui_Caching_Factory_Data Efl_Ui_Caching_Factory_Data;
typedef struct _Efl_Ui_Caching_Factory_Request Efl_Ui_Caching_Factory_Request;
+typedef struct _Efl_Ui_Caching_Factory_Group_Request Efl_Ui_Caching_Factory_Group_Request;
struct _Efl_Ui_Caching_Factory_Data
{
@@ -31,8 +34,13 @@ struct _Efl_Ui_Caching_Factory_Request
{
Efl_Ui_Caching_Factory_Data *pd;
+ Efl_Ui_Caching_Factory *factory;
Eo *parent;
- Efl_Model *model;
+};
+
+struct _Efl_Ui_Caching_Factory_Group_Request
+{
+ Eina_Value done;
};
// Clear the cache until it meet the constraint
@@ -84,88 +92,180 @@ _efl_ui_caching_factory_flush(Eo *obj, Efl_Ui_Caching_Factory_Data *pd)
}
static Eina_Value
-_efl_ui_caching_factory_create_then(Eo *obj EINA_UNUSED, void *data, const Eina_Value v)
+_efl_ui_caching_factory_uncap_then(Eo *model EINA_UNUSED,
+ void *data EINA_UNUSED,
+ const Eina_Value v)
+{
+ Efl_Ui_Widget *widget = NULL;
+
+ if (eina_value_array_count(&v) != 1) return eina_value_error_init(EINVAL);
+
+ eina_value_array_get(&v, 0, &widget);
+
+ return eina_value_object_init(widget);
+}
+
+static Eina_Value
+_efl_ui_caching_factory_create_then(Eo *model, void *data, const Eina_Value v)
{
Efl_Ui_Caching_Factory_Request *r = data;
Efl_Ui_Widget *w;
- const char *string = NULL;
+ const char *style = NULL;
- if (!eina_value_string_get(&v, &string))
+ if (!eina_value_string_get(&v, &style))
return eina_value_error_init(EFL_MODEL_ERROR_NOT_SUPPORTED);
- w = eina_hash_find(r->pd->lookup, string);
+ w = eina_hash_find(r->pd->lookup, style);
if (!w)
{
Eina_Future *f;
+ Eo *models[1] = { model };
// No object of that style in the cache, need to create a new one
- f = efl_ui_factory_create(efl_super(obj, EFL_UI_CACHING_FACTORY_CLASS),
- r->model, r->parent);
+ // This is not ideal, we would want to gather all the request in one swoop here,
+ // left for later improvement.
+ f = efl_ui_factory_create(efl_super(r->factory, EFL_UI_CACHING_FACTORY_CLASS),
+ EINA_C_ARRAY_ITERATOR_NEW(models), r->parent);
+ f = efl_future_then(r->factory, f,
+ .success = _efl_ui_caching_factory_uncap_then,
+ .success_type = EINA_VALUE_TYPE_ARRAY);
return eina_future_as_value(f);
}
- eina_hash_del(r->pd->lookup, string, w);
- _efl_ui_caching_factory_remove(r->pd, r->pd->cache, w);
+ eina_hash_del(r->pd->lookup, style, w);
+ _efl_ui_caching_factory_remove(r->pd, eina_list_data_find(r->pd->cache, w), w);
efl_parent_set(w, r->parent);
- efl_ui_view_model_set(w, r->model);
+ efl_ui_view_model_set(w, model);
return eina_value_object_init(w);
}
static void
-_efl_ui_caching_factory_create_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
+_efl_ui_caching_factory_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
{
Efl_Ui_Caching_Factory_Request *r = data;
- efl_unref(r->model);
+ efl_unref(r->factory);
efl_unref(r->parent);
free(r);
}
+static Eina_Value
+_efl_ui_caching_factory_group_create_then(Eo *obj EINA_UNUSED,
+ void *data,
+ const Eina_Value v)
+{
+ Efl_Ui_Caching_Factory_Group_Request *gr = data;
+ int len, i;
+ Efl_Ui_Widget *widget;
+
+ EINA_VALUE_ARRAY_FOREACH(&v, len, i, widget)
+ eina_value_array_append(&gr->done, widget);
+
+ return eina_value_reference_copy(&gr->done);
+}
+
+static void
+_efl_ui_caching_factory_group_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
+{
+ Efl_Ui_Caching_Factory_Group_Request *gr = data;
+
+ eina_value_flush(&gr->done);
+ free(gr);
+}
+
static Eina_Future *
_efl_ui_caching_factory_efl_ui_factory_create(Eo *obj,
Efl_Ui_Caching_Factory_Data *pd,
- Efl_Model *model, Efl_Gfx_Entity *parent)
+ Eina_Iterator *models, Efl_Gfx_Entity *parent)
{
+ Efl_Ui_Caching_Factory_Group_Request *gr;
Efl_Gfx_Entity *w = NULL;
+ Efl_Model *model;
+ Eina_Future *f;
- if (pd->cache)
+ if (pd->cache && pd->style && !pd->klass)
{
- if (pd->style && !pd->klass)
- {
- Efl_Ui_Caching_Factory_Request *r;
+ Efl_Ui_Caching_Factory_Request *r;
+ Eina_Future **all;
+ int count = 0;
- r = calloc(1, sizeof (Efl_Ui_Caching_Factory_Request));
- if (!r) return efl_loop_future_rejected(obj, ENOMEM);
+ r = calloc(1, sizeof (Efl_Ui_Caching_Factory_Request));
+ if (!r) return efl_loop_future_rejected(obj, ENOMEM);
- r->pd = pd;
- r->parent = efl_ref(parent);
- r->model = efl_ref(model);
+ r->pd = pd;
+ r->parent = efl_ref(parent);
+ r->factory = efl_ref(obj);
- return efl_future_then(obj, efl_model_property_ready_get(obj, pd->style),
- .success = _efl_ui_caching_factory_create_then,
- .data = r,
- .free = _efl_ui_caching_factory_create_cleanup);
- }
+ all = calloc(1, sizeof (Eina_Future *));
+ if (!all) return efl_loop_future_rejected(obj, ENOMEM);
+
+ EINA_ITERATOR_FOREACH(models, model)
+ {
+ all[count++] = efl_future_then(model,
+ efl_model_property_ready_get(model, pd->style),
+ .success = _efl_ui_caching_factory_create_then,
+ .data = r);
- w = eina_list_data_get(pd->cache);
+ all = realloc(all, (count + 1) * sizeof (Eina_Future *));
+ if (!all) return efl_loop_future_rejected(obj, ENOMEM);
+ }
+ eina_iterator_free(models);
- _efl_ui_caching_factory_remove(pd, pd->cache, w);
+ all[count] = EINA_FUTURE_SENTINEL;
- efl_parent_set(w, parent);
+ return efl_future_then(obj, eina_future_all_array(all),
+ .data = r,
+ .free = _efl_ui_caching_factory_cleanup);
}
- if (!w)
+ gr = calloc(1, sizeof (Efl_Ui_Caching_Factory_Group_Request));
+ if (!gr) return efl_loop_future_rejected(obj, ENOMEM);
+
+ eina_value_array_setup(&gr->done, EINA_VALUE_TYPE_OBJECT, 4);
+
+ // First get as much object from the cache as possible
+ if (pd->cache)
+ EINA_ITERATOR_FOREACH(models, model)
+ {
+ w = eina_list_data_get(pd->cache);
+ _efl_ui_caching_factory_remove(pd, pd->cache, w);
+ efl_parent_set(w, parent);
+
+ efl_ui_view_model_set(w, model);
+
+ eina_value_array_append(&gr->done, w);
+
+ if (!pd->cache) break;
+ }
+
+ // Now create object on the fly that are missing from the cache
+ if (pd->klass)
{
- if (pd->klass) w = efl_add(pd->klass, parent);
- else return efl_ui_factory_create(efl_super(obj, EFL_UI_CACHING_FACTORY_CLASS),
- model, parent);
- }
+ EINA_ITERATOR_FOREACH(models, model)
+ {
+ w = efl_add(pd->klass, parent,
+ efl_ui_factory_building(obj, efl_added),
+ efl_ui_view_model_set(efl_added, model));
+ eina_value_array_append(&gr->done, w);
+ }
- efl_ui_view_model_set(w, model);
+ f = efl_loop_future_resolved(obj, gr->done);
+
+ eina_value_flush(&gr->done);
+ free(gr);
+
+ return f;
+ }
- return efl_loop_future_resolved(obj, eina_value_object_init(w));
+ f = efl_ui_factory_create(efl_super(obj, EFL_UI_CACHING_FACTORY_CLASS),
+ models, parent);
+ return efl_future_then(obj, f,
+ .success = _efl_ui_caching_factory_group_create_then,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
+ .data = gr,
+ .free = _efl_ui_caching_factory_group_cleanup);
}
static void
diff --git a/src/lib/elementary/efl_ui_calendar.c b/src/lib/elementary/efl_ui_calendar.c
index 7fb174273f..8c21646ba9 100644
--- a/src/lib/elementary/efl_ui_calendar.c
+++ b/src/lib/elementary/efl_ui_calendar.c
@@ -70,22 +70,6 @@ static int _days_in_month[2][12] =
static Eina_Bool _efl_ui_calendar_smart_focus_next_enable = EINA_FALSE;
-EOLIAN static void
-_efl_ui_calendar_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Calendar_Data *_pd EINA_UNUSED)
-{
- Evas_Coord minw = -1, minh = -1;
- EFL_UI_CALENDAR_DATA_GET(obj, sd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- if (sd->filling) return;
- // 7x8 (1 month+year, days, 6 dates.)
- elm_coords_finger_size_adjust(7, &minw, 8, &minh);
- edje_object_size_min_restricted_calc
- (wd->resize_obj, &minw, &minh, minw, minh);
- evas_object_size_hint_min_set(obj, minw, minh);
- evas_object_size_hint_max_set(obj, -1, -1);
-}
-
// Get the max day number for each month
static inline int
_maxdays_get(struct tm *date, int month_offset)
@@ -441,7 +425,7 @@ _btn_create(Eo *obj, const char *style, char *part)
efl_ui_autorepeat_enabled_set(efl_added, EINA_TRUE),
efl_ui_autorepeat_initial_timeout_set(efl_added, FIRST_INTERVAL),
efl_ui_autorepeat_gap_timeout_set(efl_added, INTERVAL),
- efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED,
_inc_dec_btn_clicked_cb, obj),
efl_event_callback_add(efl_added, EFL_UI_AUTOREPEAT_EVENT_REPEATED,
_inc_dec_btn_repeated_cb, obj),
@@ -807,12 +791,11 @@ _efl_ui_calendar_efl_ui_focus_object_on_focus_update(Eo *obj, Efl_Ui_Calendar_Da
EOLIAN static void
_efl_ui_calendar_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Calendar_Data *_pd EINA_UNUSED)
{
- elm_layout_freeze(obj);
-
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
_set_headers(obj);
_populate(obj);
- elm_layout_thaw(obj);
+ efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
}
EOLIAN static void
@@ -944,6 +927,8 @@ _efl_ui_calendar_efl_object_constructor(Eo *obj, Efl_Ui_Calendar_Data *sd)
efl_access_object_role_set(obj, EFL_ACCESS_ROLE_DATE_EDITOR);
obj = _efl_ui_calendar_constructor_internal(obj, sd);
+ // 7x8 (1 month+year, days, 6 dates.)
+ efl_ui_layout_finger_size_multiplier_set(obj, 7, 8);
return obj;
}
@@ -1168,11 +1153,6 @@ _efl_ui_calendar_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNU
ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_calendar, Efl_Ui_Calendar_Data)
-/* Internal EO APIs and hidden overrides */
-
-#define EFL_UI_CALENDAR_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_calendar)
-
#include "efl_ui_calendar.eo.c"
typedef struct {
diff --git a/src/lib/elementary/efl_ui_check.c b/src/lib/elementary/efl_ui_check.c
index 9f575621ff..43b2a967f6 100644
--- a/src/lib/elementary/efl_ui_check.c
+++ b/src/lib/elementary/efl_ui_check.c
@@ -54,13 +54,13 @@ static void
_activate(Evas_Object *obj)
{
// state will be changed by the later call to the selected_set call
- if (!efl_ui_check_selected_get(obj))
+ if (!efl_ui_selectable_selected_get(obj))
{
// FIXME: to do animation during state change , we need different signal
// so that we can distinguish between state change by user or state change
// by calling state_change() api. Keep both the signal for backward compatibility
// and remove "elm,state,check,on" signal emission when we can break ABI.
- // efl_ui_check_selected_set below will emit "elm,state,check,*" or "efl,state,check,*"
+ // efl_ui_selectable_selected_set below will emit "elm,state,check,*" or "efl,state,check,*"
if (elm_widget_is_legacy(obj))
{
elm_layout_signal_emit(obj, "elm,activate,check,on", "elm");
@@ -79,7 +79,7 @@ _activate(Evas_Object *obj)
// so that we can distinguish between state change by user or state change
// by calling state_change() api. Keep both the signal for backward compatibility
// and remove "elm,state,check,off" signal emission when we can break ABI.
- // efl_ui_check_selected_set below will emit "elm,state,check,*" or "efl,state,check,*"
+ // efl_ui_selectable_selected_set below will emit "elm,state,check,*" or "efl,state,check,*"
if (elm_widget_is_legacy(obj))
{
elm_layout_signal_emit(obj, "elm,activate,check,off", "elm");
@@ -95,14 +95,14 @@ _activate(Evas_Object *obj)
//This commit will update the theme with the correct signals
// "elm,state,check,on" or "elm,state,check,off" for legacy
// "efl,state,check,on" or "efl,state,check,off" for eo-api
- efl_ui_check_selected_set(obj, !efl_ui_check_selected_get(obj));
+ efl_ui_selectable_selected_set(obj, !efl_ui_selectable_selected_get(obj));
if (elm_widget_is_legacy(obj))
evas_object_smart_callback_call(obj, "changed", NULL);
if (_elm_config->atspi_mode)
efl_access_state_changed_signal_emit(obj,
EFL_ACCESS_STATE_TYPE_CHECKED,
- efl_ui_check_selected_get(obj));
+ efl_ui_selectable_selected_get(obj));
}
EOLIAN static Efl_Access_State_Set
@@ -148,14 +148,14 @@ _efl_ui_check_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Check_Data *sd EINA_UNUS
if (elm_widget_is_legacy(obj))
{
- if (!efl_ui_check_selected_get(obj))
+ if (!efl_ui_selectable_selected_get(obj))
elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
else
elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
}
else
{
- if (!efl_ui_check_selected_get(obj))
+ if (!efl_ui_selectable_selected_get(obj))
elm_layout_signal_emit(obj, "efl,state,check,off", "efl");
else
elm_layout_signal_emit(obj, "efl,state,check,on", "efl");
@@ -163,8 +163,6 @@ _efl_ui_check_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Check_Data *sd EINA_UNUS
edje_object_message_signal_process(wd->resize_obj);
- elm_layout_sizing_eval(obj);
-
return int_ret;
}
@@ -186,7 +184,7 @@ _access_state_cb(void *data, Evas_Object *obj)
if (elm_widget_disabled_get(obj))
return strdup(E_("State: Disabled"));
- if (efl_ui_check_selected_get(obj))
+ if (efl_ui_selectable_selected_get(obj))
{
on_text = elm_layout_text_get(data, "on");
@@ -216,12 +214,12 @@ _access_state_cb(void *data, Evas_Object *obj)
static void
_flush_selected(Eo *obj, Eina_Bool sel)
{
- efl_ui_check_selected_set(obj, sel);
+ efl_ui_selectable_selected_set(obj, sel);
if (_elm_config->atspi_mode)
efl_access_state_changed_signal_emit(obj,
EFL_ACCESS_STATE_TYPE_CHECKED,
- efl_ui_check_selected_get(obj));
+ efl_ui_selectable_selected_get(obj));
}
static void
@@ -255,14 +253,20 @@ _on_check_toggle(void *data,
_activate(data);
}
+static void
+_clicked_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _activate(data);
+}
+
EOLIAN static Eina_Bool
-_efl_ui_check_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Check_Data *pd EINA_UNUSED)
+_efl_ui_check_efl_ui_selectable_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Check_Data *pd EINA_UNUSED)
{
return pd->selected;
}
EOLIAN static void
-_efl_ui_check_selected_set(Eo *obj, Efl_Ui_Check_Data *pd, Eina_Bool value)
+_efl_ui_check_efl_ui_selectable_selected_set(Eo *obj, Efl_Ui_Check_Data *pd, Eina_Bool value)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
@@ -294,7 +298,7 @@ _efl_ui_check_selected_set(Eo *obj, Efl_Ui_Check_Data *pd, Eina_Bool value)
pd->selected = value;
if (!elm_widget_is_legacy(obj))
- efl_event_callback_call(obj, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, &pd->selected);
+ efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED_CHANGED, &pd->selected);
}
EOLIAN static Eo *
@@ -306,7 +310,7 @@ _efl_ui_check_efl_object_constructor(Eo *obj, Efl_Ui_Check_Data *pd EINA_UNUSED)
evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
-
+ efl_ui_action_connector_bind_clickable_to_theme(wd->resize_obj, obj);
if (elm_widget_is_legacy(obj))
{
efl_layout_signal_callback_add
@@ -322,8 +326,7 @@ _efl_ui_check_efl_object_constructor(Eo *obj, Efl_Ui_Check_Data *pd EINA_UNUSED)
(wd->resize_obj, "efl,action,check,on", "*", obj, _on_check_on, NULL);
efl_layout_signal_callback_add
(wd->resize_obj, "efl,action,check,off", "*", obj, _on_check_off, NULL);
- efl_layout_signal_callback_add
- (wd->resize_obj, "efl,action,check,toggle", "*", obj, _on_check_toggle, NULL);
+ efl_event_callback_add(obj, EFL_INPUT_EVENT_CLICKED, _clicked_cb, obj);
}
efl_access_object_role_set(obj, EFL_ACCESS_ROLE_CHECK_BOX);
@@ -346,13 +349,13 @@ elm_check_state_set(Evas_Object *obj, Eina_Bool state)
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
EFL_UI_CHECK_DATA_GET_OR_RETURN(obj, sd);
- efl_ui_check_selected_set(obj, state);
+ efl_ui_selectable_selected_set(obj, state);
}
EAPI Eina_Bool
elm_check_state_get(const Evas_Object *obj)
{
- return !!efl_ui_check_selected_get(obj);
+ return !!efl_ui_selectable_selected_get(obj);
}
EAPI void
@@ -369,7 +372,7 @@ elm_check_state_pointer_set(Eo *obj, Eina_Bool *statep)
sd->statep = statep;
if (*sd->statep != sd->selected)
{
- efl_ui_check_selected_set(obj, *sd->statep);
+ efl_ui_selectable_selected_set(obj, *sd->statep);
}
}
@@ -439,7 +442,7 @@ _icon_signal_emit(Evas_Object *obj)
elm_layout_signal_emit(obj, buf, "elm");
edje_object_message_signal_process(wd->resize_obj);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
}
/* FIXME: replicated from elm_layout just because check's icon spot
diff --git a/src/lib/elementary/efl_ui_check.eo b/src/lib/elementary/efl_ui_check.eo
index 95d1635054..d3f6a39a42 100644
--- a/src/lib/elementary/efl_ui_check.eo
+++ b/src/lib/elementary/efl_ui_check.eo
@@ -1,4 +1,4 @@
-class @beta Efl.Ui.Check extends Efl.Ui.Layout_Base implements Efl.Access.Widget.Action, Efl.Text, Efl.Content
+class @beta Efl.Ui.Check extends Efl.Ui.Layout_Base implements Efl.Access.Widget.Action, Efl.Text, Efl.Content, Efl.Input.Clickable, Efl.Ui.Selectable
{
[[Check widget
@@ -8,16 +8,6 @@ class @beta Efl.Ui.Check extends Efl.Ui.Layout_Base implements Efl.Access.Widget
the value of a boolean between false and true.
]]
methods {
- @property selected {
- [[The on/off state of the check object.]]
- set {
- }
- get {
- }
- values {
- value: bool; [[$true if the check object is selected, $false otherwise]]
- }
- }
}
implements {
Efl.Object.constructor;
@@ -30,8 +20,6 @@ class @beta Efl.Ui.Check extends Efl.Ui.Layout_Base implements Efl.Access.Widget
Efl.Content.content_unset;
Efl.Text.text { get; set; }
Efl.Ui.L10n.l10n_text { get; set; }
- }
- events {
- selected,changed : bool; [[Emitted each time selected has changed]]
+ Efl.Ui.Selectable.selected {get; set; }
}
}
diff --git a/src/lib/elementary/efl_ui_check_eo.legacy.c b/src/lib/elementary/efl_ui_check_eo.legacy.c
index ea58cc9249..b2537c053a 100644
--- a/src/lib/elementary/efl_ui_check_eo.legacy.c
+++ b/src/lib/elementary/efl_ui_check_eo.legacy.c
@@ -2,11 +2,11 @@
EAPI void
elm_check_selected_set(Efl_Ui_Check *obj, Eina_Bool value)
{
- efl_ui_check_selected_set(obj, value);
+ efl_ui_selectable_selected_set(obj, value);
}
EAPI Eina_Bool
elm_check_selected_get(const Efl_Ui_Check *obj)
{
- return efl_ui_check_selected_get(obj);
+ return efl_ui_selectable_selected_get(obj);
}
diff --git a/src/lib/elementary/efl_ui_check_legacy_eo.c b/src/lib/elementary/efl_ui_check_legacy_eo.c
index cd1d466ee9..591fc2783a 100644
--- a/src/lib/elementary/efl_ui_check_legacy_eo.c
+++ b/src/lib/elementary/efl_ui_check_legacy_eo.c
@@ -44,4 +44,4 @@ static const Efl_Class_Description _efl_ui_check_legacy_class_desc = {
NULL
};
-EFL_DEFINE_CLASS(efl_ui_check_legacy_class_get, &_efl_ui_check_legacy_class_desc, EFL_UI_CHECK_CLASS, EFL_UI_LEGACY_INTERFACE, NULL);
+EFL_DEFINE_CLASS(efl_ui_check_legacy_class_get, &_efl_ui_check_legacy_class_desc, EFL_UI_CHECK_CLASS, ELM_LAYOUT_MIXIN, EFL_UI_LEGACY_INTERFACE, NULL);
diff --git a/src/lib/elementary/efl_ui_clickable.c b/src/lib/elementary/efl_ui_clickable.c
deleted file mode 100644
index ced9609e35..0000000000
--- a/src/lib/elementary/efl_ui_clickable.c
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#define EFL_UI_CLICKABLE_PROTECTED 1
-
-#include <Efl_Ui.h>
-#include "elm_priv.h"
-
-typedef struct {
- Eina_Bool pressed;
- int pressed_before;
- Efl_Loop_Timer *timer;
- double clicked_last_time;
-} Button_State;
-
-typedef struct {
- Button_State state[3];
-} Efl_Ui_Clickable_Data;
-
-#define MY_CLASS EFL_UI_CLICKABLE_MIXIN
-
-#define DOUBLE_CLICK_TIME ((double)0.1) //in seconds
-#define LONGPRESS_TIMEOUT ((double)1.0) //in seconds
-
-static void
-_timer_longpress(void *data, const Efl_Event *ev)
-{
- Button_State *state;
- Efl_Ui_Clickable_Data *pd = efl_data_scope_get(data, MY_CLASS);
-
- for (int i = 0; i < 3; ++i)
- {
- state = &pd->state[i];
- if (state->timer == ev->object)
- {
- efl_del(state->timer);
- state->timer = NULL;
- efl_event_callback_call(data, EFL_UI_EVENT_LONGPRESSED, &i);
- }
- }
-}
-
-EOLIAN static void
-_efl_ui_clickable_press(Eo *obj EINA_UNUSED, Efl_Ui_Clickable_Data *pd, unsigned int button)
-{
- Button_State *state;
- EINA_SAFETY_ON_FALSE_RETURN(button < 3);
-
- INF("Widget %s,%p is pressed(%d)", efl_class_name_get(obj), obj, button);
-
- state = &pd->state[button];
- EINA_SAFETY_ON_NULL_RETURN(state);
-
- state->pressed = EINA_TRUE;
- if (state->timer) efl_del(state->timer);
- state->timer = efl_add(EFL_LOOP_TIMER_CLASS, obj,
- efl_loop_timer_interval_set(efl_added, LONGPRESS_TIMEOUT),
- efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _timer_longpress, obj));
-
- efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, &button);
-}
-
-EOLIAN static void
-_efl_ui_clickable_unpress(Eo *obj EINA_UNUSED, Efl_Ui_Clickable_Data *pd, unsigned int button)
-{
- Efl_Ui_Clickable_Clicked clicked;
- Button_State *state;
- Eina_Bool pressed;
- EINA_SAFETY_ON_FALSE_RETURN(button < 3);
-
- state = &pd->state[button];
- EINA_SAFETY_ON_NULL_RETURN(state);
-
- INF("Widget %s,%p is unpressed(%d):%d", efl_class_name_get(obj), obj, button, state->pressed);
-
- //eval if this is a repeated click
- if (state->clicked_last_time > 0.0 && ecore_time_unix_get() - state->clicked_last_time < DOUBLE_CLICK_TIME)
- state->pressed_before++;
- else
- state->pressed_before = 0;
- //reset state
- state->clicked_last_time = ecore_time_unix_get();
- pressed = state->pressed;
- state->pressed = EINA_FALSE;
- if (state->timer)
- efl_del(state->timer);
- state->timer = NULL;
-
- //populate state
- efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, &button);
- if (pressed)
- {
- INF("Widget %s,%p is clicked(%d)", efl_class_name_get(obj), obj, button);
- clicked.repeated = state->pressed_before;
- clicked.button = button;
- if (button == 1)
- efl_event_callback_call(obj, EFL_UI_EVENT_CLICKED, &clicked);
- efl_event_callback_call(obj, EFL_UI_EVENT_CLICKED_ANY, &clicked);
- }
-}
-
-EOLIAN static void
-_efl_ui_clickable_button_state_reset(Eo *obj EINA_UNUSED, Efl_Ui_Clickable_Data *pd, unsigned int button)
-{
- Button_State *state;
- EINA_SAFETY_ON_FALSE_RETURN(button < 3);
-
- state = &pd->state[button];
- EINA_SAFETY_ON_NULL_RETURN(state);
-
- INF("Widget %s,%p is press is aborted(%d):%d", efl_class_name_get(obj), obj, button, state->pressed);
-
- if (state->timer)
- efl_del(state->timer);
- state->timer = NULL;
- state->pressed = EINA_FALSE;
-}
-
-#include "efl_ui_clickable.eo.c"
diff --git a/src/lib/elementary/efl_ui_clickable.eo b/src/lib/elementary/efl_ui_clickable.eo
deleted file mode 100644
index ace6f6d6e7..0000000000
--- a/src/lib/elementary/efl_ui_clickable.eo
+++ /dev/null
@@ -1,47 +0,0 @@
-struct @beta Efl.Ui.Clickable_Clicked {
- [[A struct that expresses a click in elementary.]]
- repeated : int; [[The amount of how often the clicked event was repeated in a certain amount of time]]
- button : int; [[The Button that is pressed]]
-}
-
-mixin @beta Efl.Ui.Clickable
-{
- [[Efl UI clickable interface]]
- event_prefix: efl_ui;
- methods {
- press @protected {
- [[Change internal states that a button got pressed.
-
- When the button is already pressed, this is silently ignored.
- ]]
- params {
- button : uint; [[The number of the button. FIXME ensure to have the right interval of possible input]]
- }
- }
- unpress @protected {
- [[Change internal states that a button got unpressed.
-
- When the button is not pressed, this is silently ignored.
- ]]
- params {
- button : uint; [[The number of the button. FIXME ensure to have the right interval of possible input]]
- }
- }
- button_state_reset @protected {
- [[This aborts the internal state after a press call.
-
- This will stop the timer for longpress. And set the state of the clickable mixin back into the unpressed state.
- ]]
- params {
- button : uint;
- }
- }
- }
- events {
- clicked: Efl.Ui.Clickable_Clicked; [[Called when object is in sequence pressed and unpressed, by the primary button]]
- clicked,any : Efl.Ui.Clickable_Clicked; [[Called when object is in sequence pressed and unpressed by any button. The button that triggered the event can be found in the event information.]]
- pressed: int; [[Called when the object is pressed, event_info is the button that got pressed]]
- unpressed: int; [[Called when the object is no longer pressed, event_info is the button that got pressed]]
- longpressed: int; [[Called when the object receives a long press, event_info is the button that got pressed]]
- }
-}
diff --git a/src/lib/elementary/efl_ui_clock.c b/src/lib/elementary/efl_ui_clock.c
index e580d3cf06..462f2be615 100644
--- a/src/lib/elementary/efl_ui_clock.c
+++ b/src/lib/elementary/efl_ui_clock.c
@@ -2,6 +2,10 @@
# include "elementary_config.h"
#endif
+#ifdef _WIN32
+# include <evil_private.h> /* nl_langinfo */
+#endif
+
#define EFL_ACCESS_OBJECT_PROTECTED
#define EFL_UI_L10N_PROTECTED
@@ -25,6 +29,7 @@
#define MAX_SEPARATOR_LEN 6
#define MIN_DAYS_IN_MONTH 28
#define BUFFER_SIZE 1024
+#define CLOCK_FIELD_COUNT 8
/* interface between EDC & C code (field & signal names). values 0 to
* EFL_UI_CLOCK_TYPE_COUNT are in the valid range, and must get in the
@@ -91,49 +96,119 @@ static void _part_name_snprintf(char *buffer, int buffer_size,
snprintf(buffer, buffer_size, template + 4, n);
}
-static Elm_Module *
-_dt_mod_find(void)
+static void
+_ampm_clicked_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ struct tm curr_time;
+
+ curr_time = efl_ui_clock_time_get(data);
+ if (curr_time.tm_hour >= 12) curr_time.tm_hour -= 12;
+ else curr_time.tm_hour += 12;
+ efl_ui_clock_time_set(data, curr_time);
+}
+
+static void
+_access_set(Evas_Object *obj, Efl_Ui_Clock_Type field_type)
{
- static int tried_fallback = 0;
- Elm_Module *mod = _elm_module_find_as("clock/api");
+ const char* type = NULL;
- if (mod) return mod;
- if (!tried_fallback &&
- (!_elm_config->modules || !strstr(_elm_config->modules, "clock/api")))
+ switch (field_type)
{
- // See also _config_update(): we hardcode here the default module
- ERR("Elementary config does not contain the required module "
- "name for the clock widget! Verify your installation.");
- _elm_module_add("clock_input_ctxpopup", "clock/api");
- mod = _elm_module_find_as("clock/api");
- tried_fallback = EINA_TRUE;
+ case EFL_UI_CLOCK_TYPE_YEAR:
+ type = "datetime field, year";
+ break;
+
+ case EFL_UI_CLOCK_TYPE_MONTH:
+ type = "datetime field, month";
+ break;
+
+ case EFL_UI_CLOCK_TYPE_DATE:
+ type = "datetime field, date";
+ break;
+
+ case EFL_UI_CLOCK_TYPE_HOUR:
+ type = "datetime field, hour";
+ break;
+
+ case EFL_UI_CLOCK_TYPE_MINUTE:
+ type = "datetime field, minute";
+ break;
+
+ case EFL_UI_CLOCK_TYPE_AMPM:
+ type = "datetime field, AM PM";
+ break;
+
+ default:
+ break;
}
- return mod;
+
+ _elm_access_text_set
+ (_elm_access_info_get(obj), ELM_ACCESS_TYPE, type);
+ _elm_access_callback_set
+ (_elm_access_info_get(obj), ELM_ACCESS_STATE, NULL, NULL);
}
-static Clock_Mod_Api *
-_dt_mod_init()
+static const char *
+_field_format_get(Evas_Object *obj,
+ Efl_Ui_Clock_Type field_type)
{
- Elm_Module *mod;
-
- mod = _dt_mod_find();
- if (!mod) return NULL;
- if (mod->api) return mod->api;
- mod->api = malloc(sizeof(Clock_Mod_Api));
- if (!mod->api) return NULL;
-
- ((Clock_Mod_Api *)(mod->api))->obj_hook =
- _elm_module_symbol_get(mod, "obj_hook");
- ((Clock_Mod_Api *)(mod->api))->obj_unhook =
- _elm_module_symbol_get(mod, "obj_unhook");
- ((Clock_Mod_Api *)(mod->api))->obj_hide =
- _elm_module_symbol_get(mod, "obj_hide");
- ((Clock_Mod_Api *)(mod->api))->field_create =
- _elm_module_symbol_get(mod, "field_create");
- ((Clock_Mod_Api *)(mod->api))->field_value_display =
- _elm_module_symbol_get(mod, "field_value_display");
-
- return mod->api;
+ Clock_Field *field;
+
+ if (field_type > EFL_UI_CLOCK_TYPE_AMPM) return NULL;
+
+ EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+ field = sd->field_list + field_type;
+
+ return field->fmt;
+}
+
+static void
+field_value_display(Eo *obj, Evas_Object *item_obj)
+{
+ Efl_Ui_Clock_Type field_type;
+ struct tm tim;
+ char buf[BUFFER_SIZE];
+ const char *fmt;
+
+ tim = efl_ui_clock_time_get(obj);
+ field_type = (Efl_Ui_Clock_Type )evas_object_data_get(item_obj, "_field_type");
+ fmt = _field_format_get(obj, field_type);
+ buf[0] = 0;
+ strftime(buf, sizeof(buf), fmt, &tim);
+ if ((!buf[0]) && ((!strcmp(fmt, "%p")) || (!strcmp(fmt, "%P"))))
+ {
+ // yes BUFFER_SIZE is more than 2 bytes!
+ if (tim.tm_hour < 12) strcpy(buf, "AM");
+ else strcpy(buf, "PM");
+ }
+ efl_text_set(item_obj, buf);
+}
+
+static Evas_Object *
+field_create(Eo *obj, Efl_Ui_Clock_Type field_type)
+{
+ Evas_Object *field_obj;
+
+ if (field_type == EFL_UI_CLOCK_TYPE_AMPM)
+ {
+ field_obj = efl_add(EFL_UI_BUTTON_CLASS, obj,
+ efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED, _ampm_clicked_cb, obj));
+ }
+ else
+ {
+ field_obj = efl_add(EFL_UI_TEXT_CLASS,obj,
+ efl_text_multiline_set(efl_added, EINA_FALSE),
+ efl_text_interactive_editable_set(efl_added, EINA_FALSE),
+ efl_ui_text_input_panel_enabled_set(efl_added, EINA_FALSE),
+ efl_ui_text_context_menu_disabled_set(efl_added, EINA_TRUE));
+ }
+ evas_object_data_set(field_obj, "_field_type", (void *)field_type);
+
+ // ACCESS
+ _access_set(field_obj, field_type);
+
+ return field_obj;
}
static void
@@ -141,18 +216,14 @@ _field_list_display(Evas_Object *obj)
{
Clock_Field *field;
unsigned int idx = 0;
- Clock_Mod_Api *dt_mod;
EFL_UI_CLOCK_DATA_GET(obj, sd);
- dt_mod = _dt_mod_init();
- if (!dt_mod || !dt_mod->field_value_display) return;
-
for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
{
field = sd->field_list + idx;
if (field->fmt_exist && field->visible)
- dt_mod->field_value_display(sd->mod_data, field->item_obj);
+ field_value_display(obj, field->item_obj);
}
}
@@ -277,17 +348,13 @@ _field_list_arrange(Evas_Object *obj)
_part_name_snprintf(buf, sizeof(buf), obj, EDC_PART_FIELD_STR,
field->location);
+ efl_gfx_entity_visible_set(efl_content_unset(efl_part(obj, buf)), EINA_FALSE);
if (field->visible && field->fmt_exist)
- {
- evas_object_hide(elm_layout_content_unset(obj, buf));
- elm_layout_content_set(obj, buf, field->item_obj);
- }
- else
- evas_object_hide(elm_layout_content_unset(obj, buf));
+ efl_content_set(efl_part(obj, buf), field->item_obj);
}
sd->freeze_sizing = freeze;
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
_field_list_display(obj);
}
@@ -401,6 +468,7 @@ _reload_format(Evas_Object *obj)
if (field->fmt_exist && field->visible)
sd->enabled_field_count++;
}
+ efl_ui_layout_finger_size_multiplier_set(obj, sd->enabled_field_count, 1);
// assign locations to disabled fields for uniform usage
for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
@@ -412,25 +480,19 @@ _reload_format(Evas_Object *obj)
{
snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
field->location);
- if (elm_widget_is_legacy(obj))
- elm_layout_signal_emit(obj, buf, "elm");
- else
- elm_layout_signal_emit(obj, buf, "efl");
+ efl_layout_signal_emit(obj, buf, "efl");
}
else
{
snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
field->location);
- if (elm_widget_is_legacy(obj))
- elm_layout_signal_emit(obj, buf, "elm");
- else
- elm_layout_signal_emit(obj, buf, "efl");
+ efl_layout_signal_emit(obj, buf, "efl");
}
if (field->location + 1)
{
_part_name_snprintf(buf, sizeof(buf), obj, EDC_PART_SEPARATOR_STR,
field->location + 1);
- elm_layout_text_set(obj, buf, field->separator);
+ efl_text_set(efl_part(obj, buf), field->separator);
}
}
@@ -478,40 +540,12 @@ _efl_ui_clock_edit_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd)
return sd->edit_mode;
}
-EOLIAN static Eina_Bool
-_efl_ui_clock_efl_ui_focus_object_on_focus_update(Eo *obj, Efl_Ui_Clock_Data *sd)
-{
- Eina_Bool int_ret = EINA_FALSE;
-
- int_ret = efl_ui_focus_object_on_focus_update(efl_super(obj, MY_CLASS));
- if (!int_ret) return EINA_FALSE;
-
- if (!efl_ui_focus_object_focus_get(obj))
- {
- Clock_Mod_Api *dt_mod = _dt_mod_init();
- if ((dt_mod) && (dt_mod->obj_hide))
- dt_mod->obj_hide(sd->mod_data);
- }
-
- return EINA_TRUE;
-}
-
EOLIAN static void
-_efl_ui_clock_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Clock_Data *sd)
+_efl_ui_clock_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Clock_Data *sd)
{
- Evas_Coord minw = -1, minh = -1;
-
- if (sd->freeze_sizing) return;
-
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- if (sd->enabled_field_count)
- elm_coords_finger_size_adjust(sd->enabled_field_count, &minw, 1, &minh);
-
- edje_object_size_min_restricted_calc
- (wd->resize_obj, &minw, &minh, minw, minh);
- evas_object_size_hint_min_set(obj, minw, minh);
- evas_object_size_hint_max_set(obj, -1, -1);
+ /* FIXME: this seems dumb */
+ if (!sd->freeze_sizing)
+ efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
}
EOLIAN static Eina_Error
@@ -522,16 +556,12 @@ _efl_ui_clock_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Clock_Data *sd)
Clock_Field *field;
char buf[BUFFER_SIZE];
unsigned int idx;
- Clock_Mod_Api *dt_mod;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
- dt_mod = _dt_mod_init();
- if ((!dt_mod) || (!dt_mod->field_value_display)) return EINA_TRUE;
-
for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
{
field = sd->field_list + idx;
@@ -541,33 +571,26 @@ _efl_ui_clock_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Clock_Data *sd)
{
snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
field->location);
- if (elm_widget_is_legacy(obj))
- elm_layout_signal_emit(obj, buf, "elm");
- else
- elm_layout_signal_emit(obj, buf, "efl");
+ efl_layout_signal_emit(obj, buf, "efl");
if (field->location)
{
_part_name_snprintf(buf, sizeof(buf), obj, EDC_PART_SEPARATOR_STR,
field->location);
- elm_layout_text_set(obj, buf, field->separator);
+ efl_text_set(efl_part(obj, buf), field->separator);
}
- dt_mod->field_value_display(sd->mod_data, field->item_obj);
+ field_value_display(obj, field->item_obj);
}
else
{
snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
field->location);
- if (elm_widget_is_legacy(obj))
- elm_layout_signal_emit(obj, buf, "elm");
- else
- elm_layout_signal_emit(obj, buf, "efl");
+ efl_layout_signal_emit(obj, buf, "efl");
}
}
edje_object_message_signal_process(wd->resize_obj);
- elm_layout_sizing_eval(obj);
return int_ret;
}
@@ -705,62 +728,6 @@ _apply_range_restrictions(struct tm *tim)
}
}
-static const char *
-_field_format_get(Evas_Object *obj,
- Efl_Ui_Clock_Type field_type)
-{
- Clock_Field *field;
-
- if (field_type > EFL_UI_CLOCK_TYPE_AMPM) return NULL;
-
- EFL_UI_CLOCK_DATA_GET(obj, sd);
-
- field = sd->field_list + field_type;
-
- return field->fmt;
-}
-
-static void
-_field_limit_get(Evas_Object *obj,
- Efl_Ui_Clock_Type field_type,
- int *range_min,
- int *range_max)
-{
- int min, max, max_days;
- Clock_Field *field;
- unsigned int idx;
-
- if (field_type > EFL_UI_CLOCK_TYPE_DAY) return;
-
- EFL_UI_CLOCK_DATA_GET(obj, sd);
-
- field = sd->field_list + field_type;
-
- min = field->min;
- max = field->max;
-
- CLOCK_TM_ARRAY(curr_timearr, &sd->curr_time);
- CLOCK_TM_ARRAY(min_timearr, &sd->min_limit);
- CLOCK_TM_ARRAY(max_timearr, &sd->max_limit);
-
- for (idx = 0; idx < field->type; idx++)
- if (*curr_timearr[idx] > *min_timearr[idx]) break;
- if ((idx == field_type) && (min < *min_timearr[field_type]))
- min = *min_timearr[field_type];
- if (field_type == EFL_UI_CLOCK_TYPE_DATE)
- {
- max_days = _max_days_get(sd->curr_time.tm_year, sd->curr_time.tm_mon);
- if (max > max_days) max = max_days;
- }
- for (idx = 0; idx < field->type; idx++)
- if (*curr_timearr[idx] < *max_timearr[idx]) break;
- if ((idx == field_type) && (max > *max_timearr[field_type]))
- max = *max_timearr[field_type];
-
- *range_min = min;
- *range_max = max;
-}
-
static void
_field_list_init(Evas_Object *obj)
{
@@ -828,11 +795,9 @@ _ticker(void *data)
if (sd->curr_time.tm_sec > 0)
{
- Clock_Mod_Api *dt_mod = _dt_mod_init();
field = sd->field_list + EFL_UI_CLOCK_TYPE_SECOND;
- if (field->fmt_exist && field->visible &&
- dt_mod && dt_mod->field_value_display)
- dt_mod->field_value_display(sd->mod_data, field->item_obj);
+ if (field->fmt_exist && field->visible)
+ field_value_display(data, field->item_obj);
}
else
_field_list_display(data);
@@ -848,7 +813,6 @@ EOLIAN static void
_efl_ui_clock_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Clock_Data *priv)
{
Clock_Field *field;
- Clock_Mod_Api *dt_mod;
int idx;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
@@ -862,33 +826,11 @@ _efl_ui_clock_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Clock_Data *priv)
elm_widget_theme_style_get(obj)) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
CRI("Failed to set layout!");
- // module - initialise module for clock
- dt_mod = _dt_mod_init();
- if (dt_mod)
+ for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
{
- if (dt_mod->obj_hook)
- {
- priv->mod_data = dt_mod->obj_hook(obj);
-
- // update module data
- if (priv->mod_data)
- {
- priv->mod_data->base = obj;
- priv->mod_data->field_limit_get = _field_limit_get;
- priv->mod_data->field_format_get = _field_format_get;
- }
- }
-
- if (dt_mod->field_create)
- {
- for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
- {
- field = priv->field_list + idx;
- field->item_obj = dt_mod->field_create(priv->mod_data, idx);
- }
- }
+ field = priv->field_list + idx;
+ field->item_obj = field_create(obj, idx);
}
- else WRN("Failed to load clock module, clock widget may not show properly!");
priv->freeze_sizing = EINA_TRUE;
@@ -899,7 +841,6 @@ _efl_ui_clock_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Clock_Data *priv)
elm_widget_can_focus_set(obj, EINA_TRUE);
priv->freeze_sizing = EINA_FALSE;
- elm_layout_sizing_eval(obj);
// ACCESS
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
@@ -923,7 +864,6 @@ _efl_ui_clock_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Clock_Data *sd)
{
Clock_Field *tmp;
unsigned int idx;
- Clock_Mod_Api *dt_mod;
ecore_timer_del(sd->ticker);
for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
@@ -933,10 +873,6 @@ _efl_ui_clock_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Clock_Data *sd)
eina_stringshare_del(tmp->separator);
}
- dt_mod = _dt_mod_init();
- if ((dt_mod) && (dt_mod->obj_unhook))
- dt_mod->obj_unhook(sd->mod_data); // module - unhook
-
efl_canvas_group_del(efl_super(obj, MY_CLASS));
}
@@ -1005,18 +941,15 @@ _efl_ui_clock_field_visible_set(Eo *obj, Efl_Ui_Clock_Data *sd, Efl_Ui_Clock_Typ
snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
field->location);
- if (elm_widget_is_legacy(obj))
- elm_layout_signal_emit(obj, buf, "elm");
- else
- elm_layout_signal_emit(obj, buf, "efl");
+ efl_layout_signal_emit(obj, buf, "efl");
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
edje_object_message_signal_process(wd->resize_obj);
_part_name_snprintf(buf, sizeof(buf), obj, EDC_PART_FIELD_STR,
field->location);
- elm_layout_content_unset(obj, buf);
- elm_layout_content_set(obj, buf, field->item_obj);
+ efl_content_unset(efl_part(obj, buf));
+ efl_content_set(efl_part(obj, buf), field->item_obj);
}
else
{
@@ -1026,28 +959,22 @@ _efl_ui_clock_field_visible_set(Eo *obj, Efl_Ui_Clock_Data *sd, Efl_Ui_Clock_Typ
snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
field->location);
- if (elm_widget_is_legacy(obj))
- elm_layout_signal_emit(obj, buf, "elm");
- else
- elm_layout_signal_emit(obj, buf, "efl");
+ efl_layout_signal_emit(obj, buf, "efl");
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
edje_object_message_signal_process(wd->resize_obj);
_part_name_snprintf(buf, sizeof(buf), obj, EDC_PART_FIELD_STR,
field->location);
- evas_object_hide(elm_layout_content_unset(obj, buf));
+ efl_gfx_entity_visible_set(efl_content_unset(efl_part(obj, buf)), EINA_FALSE);
}
sd->freeze_sizing = EINA_FALSE;
+ efl_ui_layout_finger_size_multiplier_set(obj, sd->enabled_field_count, 1);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
if (!visible) return;
- {
- Clock_Mod_Api *dt_mod = _dt_mod_init();
- if (!dt_mod || !dt_mod->field_value_display) return;
- dt_mod->field_value_display(sd->mod_data, field->item_obj);
- }
+ field_value_display(obj, field->item_obj);
}
EOLIAN static void
@@ -1163,7 +1090,6 @@ _efl_ui_clock_time_max_set(Eo *obj, Efl_Ui_Clock_Data *sd, Efl_Time maxtime)
/* Internal EO APIs and hidden overrides */
#define EFL_UI_CLOCK_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_clock), \
EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_clock)
#include "efl_ui_clock.eo.c"
diff --git a/src/lib/elementary/efl_ui_clock.eo b/src/lib/elementary/efl_ui_clock.eo
index abc7b5e48f..6b92a3cf67 100644
--- a/src/lib/elementary/efl_ui_clock.eo
+++ b/src/lib/elementary/efl_ui_clock.eo
@@ -223,8 +223,8 @@ class @beta Efl.Ui.Clock extends Efl.Ui.Layout_Base
}
implements {
Efl.Object.constructor;
+ Efl.Canvas.Group.group_calculate;
Efl.Ui.Widget.theme_apply;
- Efl.Ui.Focus.Object.on_focus_update;
Efl.Ui.L10n.translation_update;
}
events {
diff --git a/src/lib/elementary/efl_ui_clock.h b/src/lib/elementary/efl_ui_clock.h
index 1115faaf45..c883db2eee 100644
--- a/src/lib/elementary/efl_ui_clock.h
+++ b/src/lib/elementary/efl_ui_clock.h
@@ -97,8 +97,6 @@
* the corresponding user format.
*
* Clock supports six fields: Year, Month, Date, Hour, Minute, AM/PM.
- * Depending on the Clock module that is loaded, the user can see
- * different UI to select the individual field values.
*
* The individual fields of Clock can be arranged in any order according to the format
* set by application.
@@ -117,63 +115,6 @@
* The whole widget is left aligned and its size grows horizontally depending
* on the current format and each field's visible/disabled state.
*
- * Clock individual field selection is implemented in a modular style.
- * Module can be implemented as a Ctxpopup based selection or an ISE based
- * selection or even a spinner like selection etc.
- *
- * <b>Clock Module design:</b>
- *
- * The following functions are expected to be implemented in a Clock module:
- *
- * <b>Field creation:</b>
- * <pre>
- *
- * __________ __________
- * | |----- obj_hook() ---------------------->>>| |
- * | |<<<----------------returns Mod_data ------| |
- * | Clock |_______ | |
- * | widget | |Assign module call backs | Module |
- * | base |<<<____| | |
- * | | | |
- * | |----- field_create() ------------------>>>| |
- * |__________|<<<----------------returns field_obj -----|__________|
- *
- * </pre>
- *
- * <b>Field value setting:</b>
- * <pre>
- *
- * __________ __________
- * | | | |
- * | Clock |<<<----------efl_ui_clock_time_set()----| |
- * | widget | | Module |
- * | base |----display_field_value()------------>>>| |
- * |__________| |__________|
- *
- * </pre>
- *
- * <b>del_hook:</b>
- * <pre>
- * __________ __________
- * | | | |
- * | Clock |----obj_unhook()-------------------->>>>| |
- * | widget | | Module |
- * | base | <<<-----frees mod_data---------| |
- * |__________| |__________|
- *
- * </pre>
- *
- *
- * Any module can use the following shared functions that are implemented in efl_ui_clock.c :
- *
- * <b>field_format_get()</b> - gives the field format.
- *
- * <b>field_limit_get()</b> - gives the field minimum, maximum limits.
- *
- * To enable a module, set the ELM_MODULES environment variable as shown:
- *
- * <b>export ELM_MODULES="clock_input_ctxpopup>clock/api"</b>
- *
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for Clock objects.
*
diff --git a/src/lib/elementary/efl_ui_collection.c b/src/lib/elementary/efl_ui_collection.c
new file mode 100644
index 0000000000..c7101fdbd5
--- /dev/null
+++ b/src/lib/elementary/efl_ui_collection.c
@@ -0,0 +1,1023 @@
+#ifdef HAVE_CONFIG_H
+#include "elementary_config.h"
+#endif
+
+#define ELM_LAYOUT_PROTECTED
+#define EFL_UI_SCROLL_MANAGER_PROTECTED
+#define EFL_UI_SCROLLBAR_PROTECTED
+#define EFL_UI_WIDGET_FOCUS_MANAGER_PROTECTED
+
+#include <Efl_Ui.h>
+#include <Elementary.h>
+#include "elm_widget.h"
+#include "elm_priv.h"
+#include "efl_ui_collection_focus_manager.eo.h"
+
+typedef struct {
+ Eo *collection;
+} Efl_Ui_Collection_Focus_Manager_Data;
+
+typedef struct {
+ unsigned int last_index;
+ const Eina_List *current;
+ Eina_List **items;
+} Fast_Accessor;
+
+static const Eina_List*
+_fast_accessor_get_at(Fast_Accessor *accessor, unsigned int idx)
+{
+ const Eina_List *over;
+ unsigned int middle;
+ unsigned int i;
+
+ if (idx >= eina_list_count(*accessor->items))
+ return NULL;
+
+ if (accessor->last_index == idx)
+ over = accessor->current;
+ else if (idx > accessor->last_index)
+ {
+ /* After current position. */
+ middle = ((eina_list_count(*accessor->items) - accessor->last_index))/2;
+
+ if (idx > middle)
+ /* Go backward from the end. */
+ for (i = eina_list_count(*accessor->items) - 1,
+ over = eina_list_last(*accessor->items);
+ i > idx && over;
+ --i, over = eina_list_prev(over))
+ ;
+ else
+ /* Go forward from current. */
+ for (i = accessor->last_index, over = accessor->current;
+ i < idx && over;
+ ++i, over = eina_list_next(over))
+ ;
+ }
+ else
+ {
+ /* Before current position. */
+ middle = accessor->last_index/2;
+
+ if (idx > middle)
+ /* Go backward from current. */
+ for (i = accessor->last_index, over = accessor->current;
+ i > idx && over;
+ --i, over = eina_list_prev(over))
+ ;
+ else
+ /* Go forward from start. */
+ for (i = 0, over = *accessor->items;
+ i < idx && over;
+ ++i, over = eina_list_next(over))
+ ;
+ }
+
+ if (!over)
+ return NULL;
+
+ accessor->last_index = idx;
+ accessor->current = over;
+
+ return over;
+}
+
+static void
+_fast_accessor_init(Fast_Accessor *accessor, Eina_List **items)
+{
+ //this is the accessor for accessing the items
+ //we have to workarround here the problem that
+ //no accessor can be created for a not yet created list.
+ accessor->items = items;
+}
+
+static void
+_fast_accessor_remove(Fast_Accessor *accessor, const Eina_List *removed_elem)
+{
+ if (accessor->current == removed_elem)
+ {
+ Eina_List *next;
+ Eina_List *prev;
+
+ next = eina_list_next(removed_elem);
+ prev = eina_list_prev(removed_elem);
+ if (next)
+ {
+ accessor->current = next;
+ accessor->last_index ++;
+ }
+ else if (prev)
+ {
+ accessor->current = prev;
+ accessor->last_index --;
+ }
+ else
+ {
+ //everything >= length is invalid, and we need that.
+ accessor->last_index = eina_list_count(*accessor->items);
+ accessor->current = NULL;
+ }
+
+ }
+
+}
+
+#define MY_CLASS EFL_UI_COLLECTION_CLASS
+
+#define MY_DATA_GET(obj, pd) \
+ Efl_Ui_Collection_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+
+typedef struct {
+ Efl_Ui_Scroll_Manager *smanager;
+ Efl_Ui_Pan *pan;
+ Eina_List *selected;
+ Eina_List *items;
+ Efl_Ui_Select_Mode mode;
+ Efl_Ui_Layout_Orientation dir;
+ Eina_Size2D content_min_size;
+ Efl_Ui_Position_Manager_Entity *pos_man;
+ struct {
+ Eina_Bool w;
+ Eina_Bool h;
+ } match_content;
+ Fast_Accessor obj_accessor;
+ Fast_Accessor size_accessor;
+ Efl_Gfx_Entity *sizer;
+ unsigned int start_id, end_id;
+} Efl_Ui_Collection_Data;
+
+static Eina_Bool register_item(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item);
+static Eina_Bool unregister_item(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item);
+
+static void
+flush_min_size(Eo *obj, Efl_Ui_Collection_Data *pd)
+{
+ Eina_Size2D tmp = pd->content_min_size;
+
+ if (!pd->match_content.w)
+ tmp.w = -1;
+
+ if (!pd->match_content.h)
+ tmp.h = -1;
+
+ efl_gfx_hint_size_restricted_min_set(obj, tmp);
+}
+
+static int
+clamp_index(Efl_Ui_Collection_Data *pd, int index)
+{
+ if (index < ((int)eina_list_count(pd->items)) * -1)
+ return -1;
+ else if (index > (int)eina_list_count(pd->items) - 1)
+ return 1;
+ return 0;
+}
+
+static int
+index_adjust(Efl_Ui_Collection_Data *pd, int index)
+{
+ int c = eina_list_count(pd->items);
+ if (index < c * -1)
+ return 0;
+ else if (index > c - 1)
+ return c - 1;
+ else if (index < 0)
+ return index + c;
+ return index;
+}
+
+static void
+_pan_viewport_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ MY_DATA_GET(data, pd);
+ Eina_Rect rect = efl_ui_scrollable_viewport_geometry_get(data);
+
+ efl_ui_position_manager_entity_viewport_set(pd->pos_man, rect);
+}
+
+static void
+_pan_position_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ MY_DATA_GET(data, pd);
+ Eina_Position2D pos = efl_ui_pan_position_get(pd->pan);
+ Eina_Position2D max = efl_ui_pan_position_max_get(pd->pan);
+ Eina_Vector2 rpos = {0.0, 0.0};
+
+ if (max.x > 0.0)
+ rpos.x = (double)pos.x/(double)max.x;
+ if (max.y > 0.0)
+ rpos.y = (double)pos.y/(double)max.y;
+
+ efl_ui_position_manager_entity_scroll_position_set(pd->pos_man, rpos.x, rpos.y);
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(pan_events_cb,
+ {EFL_UI_PAN_EVENT_PAN_POSITION_CHANGED, _pan_position_changed_cb},
+ {EFL_UI_PAN_EVENT_PAN_VIEWPORT_CHANGED, _pan_viewport_changed_cb},
+)
+
+static void
+_item_scroll_internal(Eo *obj EINA_UNUSED,
+ Efl_Ui_Collection_Data *pd,
+ Efl_Ui_Item *item,
+ double align EINA_UNUSED,
+ Eina_Bool anim)
+{
+ Eina_Rect ipos, view;
+ Eina_Position2D vpos;
+
+ if (!pd->smanager) return;
+
+ ipos = efl_ui_position_manager_entity_position_single_item(pd->pos_man, eina_list_data_idx(pd->items, item));
+ view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
+ vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
+
+ ipos.x = ipos.x + vpos.x - view.x;
+ ipos.y = ipos.y + vpos.y - view.y;
+
+ //FIXME scrollable needs some sort of align, the docs do not even garantee to completly move in the element
+ efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
+}
+
+EOLIAN static void
+_efl_ui_collection_item_scroll(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item, Eina_Bool animation)
+{
+ _item_scroll_internal(obj, pd, item, -1.0, animation);
+}
+
+EOLIAN static void
+_efl_ui_collection_item_scroll_align(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item, double align, Eina_Bool animation)
+{
+ _item_scroll_internal(obj, pd, item, align, animation);
+}
+
+EOLIAN static Efl_Ui_Selectable*
+_efl_ui_collection_efl_ui_single_selectable_last_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ return eina_list_last_data_get(pd->selected);
+}
+
+EOLIAN static Eina_Iterator*
+_efl_ui_collection_efl_ui_multi_selectable_selected_items_get(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ return eina_list_iterator_new(pd->selected);
+}
+
+static inline void
+_fill_group_flag(Eo *item, Efl_Ui_Position_Manager_Batch_Group_State *flag)
+{
+ if (efl_isa(item, EFL_UI_GROUP_ITEM_CLASS))
+ *flag = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP;
+ else if (efl_ui_item_parent_get(item))
+ *flag = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_PART_OF_GROUP;
+ else
+ *flag = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP;
+}
+
+static Efl_Ui_Position_Manager_Batch_Result
+_size_accessor_get_at(void *data, int start_id, Eina_Rw_Slice memory)
+{
+ Fast_Accessor *accessor = data;
+ size_t i;
+ const Eina_List *lst = _fast_accessor_get_at(accessor, start_id);
+ Efl_Ui_Position_Manager_Batch_Size_Access *sizes = memory.mem;
+ Efl_Ui_Position_Manager_Batch_Result result = {-1, 0};
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(lst, result);
+
+ for (i = 0; i < memory.len; ++i)
+ {
+ Efl_Gfx_Entity *geom = eina_list_data_get(lst), *parent;
+ Eina_Size2D size = efl_gfx_hint_size_min_get(geom);
+
+ parent = efl_ui_item_parent_get(geom);
+ sizes[i].size = size;
+ _fill_group_flag(geom, &sizes[i].group);
+ if (i == 0 && sizes[0].group != EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP && parent)
+ {
+ result.group_id = efl_pack_index_get(efl_ui_item_container_get(parent), parent);
+ }
+ lst = eina_list_next(lst);
+ if (!lst)
+ {
+ i++;
+ break;
+ }
+ }
+ result.filled_items = i;
+
+ return result;
+}
+
+static Efl_Ui_Position_Manager_Batch_Result
+_obj_accessor_get_at(void *data, int start_id, Eina_Rw_Slice memory)
+{
+ Fast_Accessor *accessor = data;
+ size_t i;
+ const Eina_List *lst = _fast_accessor_get_at(accessor, start_id);
+ Efl_Ui_Position_Manager_Batch_Entity_Access *objs = memory.mem;
+ Efl_Ui_Position_Manager_Batch_Result result = {-1, 0};
+
+ for (i = 0; i < memory.len; ++i)
+ {
+ Efl_Gfx_Entity *geom = eina_list_data_get(lst), *parent;
+
+ parent = efl_ui_item_parent_get(geom);
+ objs[i].entity = geom;
+ _fill_group_flag(geom, &objs[i].group);
+ if (i == 0 && objs[0].group != EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP && parent)
+ {
+ result.group_id = efl_pack_index_get(efl_ui_item_container_get(parent), parent);
+ }
+
+ lst = eina_list_next(lst);
+ if (!lst)
+ {
+ i++;
+ break;
+ }
+ }
+ result.filled_items = i;
+
+ return result;
+}
+
+EOLIAN static Efl_Object*
+_efl_ui_collection_efl_object_constructor(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED)
+{
+ Eo *o;
+
+ pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
+
+ _fast_accessor_init(&pd->obj_accessor, &pd->items);
+ _fast_accessor_init(&pd->size_accessor, &pd->items);
+
+ if (!elm_widget_theme_klass_get(obj))
+ elm_widget_theme_klass_set(obj, "item_container");
+
+ o = efl_constructor(efl_super(obj, MY_CLASS));
+
+ pd->sizer = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(obj));
+ efl_gfx_color_set(pd->sizer, 0, 0, 0, 0);
+
+ pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
+ efl_content_set(pd->pan, pd->sizer);
+ efl_event_callback_array_add(pd->pan, pan_events_cb(), obj);
+
+ pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
+ efl_composite_attach(obj, pd->smanager);
+ efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
+ efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
+
+ efl_ui_scroll_connector_bind(obj, pd->smanager);
+
+ return o;
+}
+
+EOLIAN static Efl_Object*
+_efl_ui_collection_efl_object_finalize(Eo *obj, Efl_Ui_Collection_Data *pd)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pd->pos_man, NULL);
+
+ return efl_finalize(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static Eina_Error
+_efl_ui_collection_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Collection_Data *pd)
+{
+ Eina_Error res;
+
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_ERROR_GENERIC);
+ res = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
+ if (res == EFL_UI_THEME_APPLY_ERROR_GENERIC) return res;
+ efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
+ efl_content_set(efl_part(wd->resize_obj, "efl.content"), pd->pan);
+
+ return res;
+}
+
+EOLIAN static void
+_efl_ui_collection_efl_object_destructor(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+static void
+deselect_all(Efl_Ui_Collection_Data *pd)
+{
+ while(pd->selected)
+ {
+ Eo *item = eina_list_data_get(pd->selected);
+ efl_ui_selectable_selected_set(item, EINA_FALSE);
+ EINA_SAFETY_ON_TRUE_RETURN(eina_list_data_get(pd->selected) == item);
+ }
+}
+
+EOLIAN static void
+_efl_ui_collection_efl_object_invalidate(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED)
+{
+ efl_ui_collection_position_manager_set(obj, NULL);
+
+ deselect_all(pd);
+
+ while(pd->items)
+ efl_del(pd->items->data);
+
+ efl_invalidate(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static Eina_Iterator*
+_efl_ui_collection_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ return eina_list_iterator_new(pd->items);
+}
+
+EOLIAN static int
+_efl_ui_collection_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ return eina_list_count(pd->items);
+}
+
+EOLIAN static void
+_efl_ui_collection_efl_ui_layout_orientable_orientation_set(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, Efl_Ui_Layout_Orientation dir)
+{
+ if (pd->dir == dir) return;
+
+ pd->dir = dir;
+ if (pd->pos_man)
+ efl_ui_layout_orientation_set(pd->pos_man, dir);
+}
+
+EOLIAN static Efl_Ui_Layout_Orientation
+_efl_ui_collection_efl_ui_layout_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ return pd->dir;
+}
+
+EOLIAN static void
+_efl_ui_collection_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, Eina_Bool w, Eina_Bool h)
+{
+ if (pd->match_content.w == w && pd->match_content.h == h)
+ return;
+
+ pd->match_content.w = w;
+ pd->match_content.h = h;
+
+ efl_ui_scrollable_match_content_set(pd->smanager, w, h);
+ flush_min_size(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_collection_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, Efl_Ui_Select_Mode mode)
+{
+ pd->mode = mode;
+ if ((mode == EFL_UI_SELECT_MODE_SINGLE_ALWAYS || mode == EFL_UI_SELECT_MODE_SINGLE) &&
+ eina_list_count(pd->selected) > 0)
+ {
+ Efl_Ui_Item *last = eina_list_last_data_get(pd->selected);
+
+ pd->selected = eina_list_remove_list(pd->selected, eina_list_last(pd->selected));
+ deselect_all(pd);
+ pd->selected = eina_list_append(pd->selected, last);
+ }
+ else if (mode == EFL_UI_SELECT_MODE_NONE && pd->selected)
+ {
+ deselect_all(pd);
+ }
+}
+
+EOLIAN static Efl_Ui_Select_Mode
+_efl_ui_collection_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ return pd->mode;
+}
+
+static void
+_selection_changed(void *data, const Efl_Event *ev)
+{
+ Eina_Bool selection = *((Eina_Bool*) ev->info);
+ Eo *obj = data;
+ MY_DATA_GET(obj, pd);
+
+ if (selection)
+ {
+ if (pd->mode == EFL_UI_SELECT_MODE_SINGLE_ALWAYS || pd->mode == EFL_UI_SELECT_MODE_SINGLE)
+ {
+ //we might get the situation that the item is already in the list and selected again, so just free the list, it will be rebuild below
+ if (eina_list_data_get(pd->selected) == ev->object)
+ {
+ pd->selected = eina_list_free(pd->selected);
+ }
+ else
+ {
+ deselect_all(pd);
+ }
+
+ }
+ else if (pd->mode == EFL_UI_SELECT_MODE_NONE)
+ {
+ ERR("Selection while mode is NONE, uncaught state!");
+ return;
+ }
+ pd->selected = eina_list_append(pd->selected, ev->object);
+ efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_SELECTED, ev->object);
+ }
+ else
+ {
+ pd->selected = eina_list_remove(pd->selected, ev->object);
+ efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_UNSELECTED, ev->object);
+ }
+}
+
+static void
+_invalidate_cb(void *data, const Efl_Event *ev)
+{
+ Eo *obj = data;
+ MY_DATA_GET(obj, pd);
+
+ unregister_item(obj, pd, ev->object);
+}
+
+static void
+_hints_changed_cb(void *data, const Efl_Event *ev)
+{
+ Eo *obj = data;
+ MY_DATA_GET(obj, pd);
+ int idx = eina_list_data_idx(pd->items, ev->object);
+
+ efl_ui_position_manager_entity_item_size_changed(pd->pos_man, idx, idx);
+}
+
+static void
+_redirect_cb(void *data, const Efl_Event *ev)
+{
+ Eo *obj = data;
+
+#define REDIRECT_EVT(item_evt, item) \
+ if (item_evt == ev->desc) efl_event_callback_call(obj, item, ev->object);
+ REDIRECT_EVT(EFL_INPUT_EVENT_PRESSED, EFL_UI_EVENT_ITEM_PRESSED);
+ REDIRECT_EVT(EFL_INPUT_EVENT_UNPRESSED, EFL_UI_EVENT_ITEM_UNPRESSED);
+ REDIRECT_EVT(EFL_INPUT_EVENT_LONGPRESSED, EFL_UI_EVENT_ITEM_LONGPRESSED);
+ REDIRECT_EVT(EFL_INPUT_EVENT_CLICKED_ANY, EFL_UI_EVENT_ITEM_CLICKED_ANY);
+ REDIRECT_EVT(EFL_INPUT_EVENT_CLICKED, EFL_UI_EVENT_ITEM_CLICKED);
+#undef REDIRECT_EVT
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(active_item,
+ {EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _hints_changed_cb},
+ {EFL_UI_EVENT_SELECTED_CHANGED, _selection_changed},
+ {EFL_INPUT_EVENT_PRESSED, _redirect_cb},
+ {EFL_INPUT_EVENT_UNPRESSED, _redirect_cb},
+ {EFL_INPUT_EVENT_LONGPRESSED, _redirect_cb},
+ {EFL_INPUT_EVENT_CLICKED, _redirect_cb},
+ {EFL_INPUT_EVENT_CLICKED_ANY, _redirect_cb},
+ {EFL_EVENT_INVALIDATE, _invalidate_cb},
+)
+
+static Eina_Bool
+register_item(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(item, EFL_UI_ITEM_CLASS), EINA_FALSE);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(!!eina_list_data_find(pd->items, item), EINA_FALSE);
+
+ if (!efl_ui_widget_sub_object_add(obj, item))
+ return EINA_FALSE;
+
+ efl_ui_item_container_set(item, obj);
+ efl_canvas_group_member_add(pd->pan, item);
+ efl_event_callback_array_add(item, active_item(), obj);
+ efl_ui_mirrored_set(item, efl_ui_mirrored_get(obj));
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+unregister_item(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item)
+{
+ Eina_List *elem = eina_list_data_find_list(pd->items, item);
+ if (!elem)
+ {
+ ERR("Item %p is not part of this widget", item);
+ return EINA_FALSE;
+ }
+
+ if (!efl_ui_widget_sub_object_del(obj, item))
+ return EINA_FALSE;
+
+ unsigned int id = eina_list_data_idx(pd->items, item);
+
+ _fast_accessor_remove(&pd->obj_accessor, elem);
+ _fast_accessor_remove(&pd->size_accessor, elem);
+
+ pd->items = eina_list_remove(pd->items, item);
+ pd->selected = eina_list_remove(pd->selected, item);
+ efl_event_callback_array_del(item, active_item(), obj);
+ efl_ui_position_manager_entity_item_removed(pd->pos_man, id, item);
+ efl_ui_item_container_set(item, NULL);
+
+ return EINA_TRUE;
+}
+
+static void
+update_pos_man(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ int id = eina_list_data_idx(pd->items, subobj);
+ if (id == 0)
+ {
+ pd->obj_accessor.last_index = id;
+ pd->obj_accessor.current = pd->items;
+ pd->size_accessor.last_index = id;
+ pd->size_accessor.current = pd->items;
+ }
+ efl_ui_position_manager_entity_item_added(pd->pos_man, id, subobj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_pack_clear(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ while(pd->items)
+ {
+ efl_del(pd->items->data);
+ }
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_unpack_all(Eo *obj, Efl_Ui_Collection_Data *pd)
+{
+ while(pd->items)
+ {
+ if (!unregister_item(obj, pd, pd->items->data))
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+EOLIAN static Efl_Gfx_Entity*
+_efl_ui_collection_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Collection_Data *pd, int index)
+{
+ Efl_Ui_Item *it = eina_list_nth(pd->items, index_adjust(pd, index));
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL);
+
+ if (!unregister_item(obj, pd, it))
+ return NULL;
+
+ return it;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_unpack(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ return unregister_item(obj, pd, subobj);
+}
+
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_pack(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
+{
+ return efl_pack_end(obj, subobj);
+}
+
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ if (!register_item(obj, pd, subobj))
+ return EINA_FALSE;
+ pd->items = eina_list_append(pd->items, subobj);
+ update_pos_man(obj, pd, subobj);
+ return EINA_TRUE;
+}
+
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ if (!register_item(obj, pd, subobj))
+ return EINA_FALSE;
+ pd->items = eina_list_prepend(pd->items, subobj);
+ update_pos_man(obj, pd, subobj);
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
+{
+ Eina_List *subobj_list = eina_list_data_find_list(pd->items, existing);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(subobj_list, EINA_FALSE);
+
+ if (!register_item(obj, pd, subobj))
+ return EINA_FALSE;
+ pd->items = eina_list_prepend_relative_list(pd->items, subobj, subobj_list);
+ update_pos_man(obj, pd, subobj);
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
+{
+ Eina_List *subobj_list = eina_list_data_find_list(pd->items, existing);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(subobj_list, EINA_FALSE);
+
+ if (!register_item(obj, pd, subobj))
+ return EINA_FALSE;
+ pd->items = eina_list_append_relative_list(pd->items, subobj, subobj_list);
+ update_pos_man(obj, pd, subobj);
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj, int index)
+{
+ Eina_List *subobj_list;
+ int clamp;
+
+ clamp = clamp_index(pd, index);
+ index = index_adjust(pd, index);
+ subobj_list = eina_list_nth_list(pd->items, index);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(subobj_list, EINA_FALSE);
+ if (!register_item(obj, pd, subobj))
+ return EINA_FALSE;
+ if (clamp == 0)
+ pd->items = eina_list_prepend_relative_list(pd->items, subobj, subobj_list);
+ else if (clamp == 1)
+ pd->items = eina_list_append(pd->items, subobj);
+ else
+ pd->items = eina_list_prepend(pd->items, subobj);
+ update_pos_man(obj, pd, subobj);
+ return EINA_TRUE;
+}
+
+EOLIAN static int
+_efl_ui_collection_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, const Efl_Gfx_Entity *subobj)
+{
+ return eina_list_data_idx(pd->items, (void*)subobj);
+}
+
+EOLIAN static Efl_Gfx_Entity*
+_efl_ui_collection_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, int index)
+{
+ return eina_list_nth(pd->items, index_adjust(pd, index));
+}
+
+static void
+_pos_content_size_changed_cb(void *data, const Efl_Event *ev)
+{
+ Eina_Size2D *size = ev->info;
+ MY_DATA_GET(data, pd);
+
+ efl_gfx_entity_size_set(pd->sizer, *size);
+}
+
+static void
+_pos_content_min_size_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ Eina_Size2D *size = ev->info;
+ MY_DATA_GET(data, pd);
+
+ pd->content_min_size = *size;
+
+ flush_min_size(data, pd);
+}
+
+static void
+_visible_range_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ Efl_Ui_Position_Manager_Range_Update *info = ev->info;
+ MY_DATA_GET(data, pd);
+
+ pd->start_id = info->start_id;
+ pd->end_id = info->end_id;
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(pos_manager_cbs,
+ {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_SIZE_CHANGED, _pos_content_size_changed_cb},
+ {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, _pos_content_min_size_changed_cb},
+ {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_VISIBLE_RANGE_CHANGED, _visible_range_changed_cb}
+)
+
+EOLIAN static void
+_efl_ui_collection_position_manager_set(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Position_Manager_Entity *layouter)
+{
+ if (layouter)
+ EINA_SAFETY_ON_FALSE_RETURN(efl_isa(layouter, EFL_UI_POSITION_MANAGER_ENTITY_INTERFACE));
+
+ if (pd->pos_man)
+ {
+ efl_event_callback_array_del(pd->pos_man, pos_manager_cbs(), obj);
+ efl_ui_position_manager_entity_data_access_set(pd->pos_man, NULL, NULL, NULL, NULL, NULL, NULL, 0);
+ efl_del(pd->pos_man);
+ }
+ pd->pos_man = layouter;
+ if (pd->pos_man)
+ {
+ efl_parent_set(pd->pos_man, obj);
+ efl_event_callback_array_add(pd->pos_man, pos_manager_cbs(), obj);
+ //efl_ui_position_manager_entity_data_access_set(pd->pos_man, &pd->obj_accessor.acc, &pd->size_accessor.acc, eina_list_count(pd->items));
+ efl_ui_position_manager_entity_data_access_set(pd->pos_man,
+ &pd->obj_accessor, _obj_accessor_get_at, NULL,
+ &pd->size_accessor, _size_accessor_get_at, NULL,
+ eina_list_count(pd->items));
+ efl_ui_position_manager_entity_viewport_set(pd->pos_man, efl_ui_scrollable_viewport_geometry_get(obj));
+ efl_ui_layout_orientation_set(pd->pos_man, pd->dir);
+ }
+}
+
+EOLIAN static Efl_Ui_Position_Manager_Entity*
+_efl_ui_collection_position_manager_get(const Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd)
+{
+ return pd->pos_man;
+}
+
+EOLIAN static Efl_Ui_Focus_Manager*
+_efl_ui_collection_efl_ui_widget_focus_manager_focus_manager_create(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root)
+{
+ Eo *man = efl_add(EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS, obj,
+ efl_ui_focus_manager_root_set(efl_added, root));
+ Efl_Ui_Collection_Focus_Manager_Data *fm_pd = efl_data_scope_safe_get(man, EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS);
+ fm_pd->collection = obj;
+ return man;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_collection_efl_ui_widget_focus_state_apply(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED, Efl_Ui_Widget_Focus_State current_state, Efl_Ui_Widget_Focus_State *configured_state, Efl_Ui_Widget *redirect EINA_UNUSED)
+{
+ return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj);
+}
+
+static Efl_Ui_Item *
+_find_item(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd EINA_UNUSED, Eo *focused_element)
+{
+ if (!focused_element) return NULL;
+
+ while (focused_element && !efl_isa(focused_element, EFL_UI_ITEM_CLASS))
+ {
+ focused_element = efl_ui_widget_parent_get(focused_element);
+ }
+
+ return focused_element;
+}
+
+EOLIAN static Efl_Ui_Focus_Object*
+_efl_ui_collection_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Focus_Direction direction)
+{
+ Eo *new_obj, *focus;
+ Eina_Size2D step;
+
+ focus = efl_ui_focus_manager_focus_get(obj);
+ new_obj = efl_ui_focus_manager_move(efl_super(obj, MY_CLASS), direction);
+ step = efl_gfx_hint_size_combined_min_get(focus);
+
+ if (new_obj)
+ {
+ /* if this is outside the viewport, then we must bring that in first */
+ Eina_Rect viewport;
+ Eina_Rect element;
+ element = efl_gfx_entity_geometry_get(focus);
+ viewport = efl_gfx_entity_geometry_get(obj);
+ if (!eina_spans_intersect(element.x, element.w, viewport.x, viewport.w) &&
+ !eina_spans_intersect(element.y, element.h, viewport.y, viewport.h))
+ {
+ efl_ui_scrollable_scroll(obj, element, EINA_TRUE);
+ return focus;
+ }
+ }
+
+ if (!new_obj)
+ {
+ Eina_Rect pos = efl_gfx_entity_geometry_get(focus);
+ Eina_Rect view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
+ Eina_Position2D vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
+
+ pos.x = pos.x + vpos.x - view.x;
+ pos.y = pos.y + vpos.y - view.y;
+ Eina_Position2D max = efl_ui_pan_position_max_get(pd->pan);
+
+ if (direction == EFL_UI_FOCUS_DIRECTION_RIGHT)
+ {
+ if (pos.x < max.x)
+ {
+ pos.x = MIN(max.x, pos.x + step.w);
+ efl_ui_scrollable_scroll(obj, pos, EINA_TRUE);
+ new_obj = focus;
+ }
+ }
+ else if (direction == EFL_UI_FOCUS_DIRECTION_LEFT)
+ {
+ if (pos.x > 0)
+ {
+ pos.x = MAX(0, pos.x - step.w);
+ efl_ui_scrollable_scroll(obj, pos, EINA_TRUE);
+ new_obj = focus;
+ }
+ }
+ else if (direction == EFL_UI_FOCUS_DIRECTION_UP)
+ {
+ if (pos.y > 0)
+ {
+ pos.y = MAX(0, pos.y - step.h);
+ efl_ui_scrollable_scroll(obj, pos, EINA_TRUE);
+ new_obj = focus;
+ }
+ }
+ else if (direction == EFL_UI_FOCUS_DIRECTION_DOWN)
+ {
+ if (pos.y < max.y)
+ {
+ pos.y = MAX(0, pos.y + step.h);
+ efl_ui_scrollable_scroll(obj, pos, EINA_TRUE);
+ new_obj = focus;
+ }
+ }
+ }
+ else
+ {
+ _item_scroll_internal(obj, pd, new_obj, .0, EINA_TRUE);
+ }
+
+ return new_obj;
+}
+
+#include "efl_ui_collection.eo.c"
+
+#define ITEM_IS_OUTSIDE_VISIBLE(id) id < collection_pd->start_id || id > collection_pd->end_id
+
+static inline void
+_assert_item_available(Eo *item, int new_id, Efl_Ui_Collection_Data *pd)
+{
+ efl_gfx_entity_visible_set(item, EINA_TRUE);
+ efl_gfx_entity_geometry_set(item, efl_ui_position_manager_entity_position_single_item(pd->pos_man, new_id));
+}
+
+EOLIAN static Efl_Ui_Focus_Object*
+_efl_ui_collection_focus_manager_efl_ui_focus_manager_request_move(Eo *obj, Efl_Ui_Collection_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction, Efl_Ui_Focus_Object *child, Eina_Bool logical)
+{
+ MY_DATA_GET(pd->collection, collection_pd);
+ Efl_Ui_Item *new_item, *item;
+ unsigned int item_id;
+
+ if (!child)
+ child = efl_ui_focus_manager_focus_get(obj);
+
+ item = _find_item(obj, collection_pd, child);
+
+ //if this is NULL then we are before finalize, we cannot serve any sane value here
+ if (!collection_pd->pos_man) return NULL;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);
+
+ item_id = efl_ui_item_index_get(item);
+
+ if (ITEM_IS_OUTSIDE_VISIBLE(item_id))
+ {
+ int new_id = efl_ui_position_manager_entity_relative_item(collection_pd->pos_man, efl_ui_item_index_get(item), direction);
+ if (new_id == -1)
+ {
+ new_item = NULL;
+ }
+ else
+ {
+ new_item = eina_list_nth(collection_pd->items, new_id);;
+ _assert_item_available(new_item, new_id, collection_pd);
+ }
+ }
+ else
+ {
+ new_item = efl_ui_focus_manager_request_move(efl_super(obj, EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS), direction, child, logical);
+ }
+
+ return new_item;
+}
+
+
+EOLIAN static void
+_efl_ui_collection_focus_manager_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_Ui_Collection_Focus_Manager_Data *pd, Efl_Ui_Focus_Object *focus)
+{
+ MY_DATA_GET(pd->collection, collection_pd);
+ Efl_Ui_Item *item;
+ unsigned int item_id;
+
+ if (focus == efl_ui_focus_manager_root_get(obj))
+ {
+ item = eina_list_data_get(collection_pd->items);
+ }
+ else
+ {
+ item = _find_item(obj, collection_pd, focus);
+ }
+
+ //if this is NULL then we are before finalize, we cannot serve any sane value here
+ if (!collection_pd->pos_man) return;
+ EINA_SAFETY_ON_NULL_RETURN(item);
+
+ item_id = efl_ui_item_index_get(item);
+
+ if (ITEM_IS_OUTSIDE_VISIBLE(item_id))
+ {
+ _assert_item_available(item, item_id, collection_pd);
+ }
+ efl_ui_focus_manager_focus_set(efl_super(obj, EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS), focus);
+}
+
+#include "efl_ui_collection_focus_manager.eo.c"
diff --git a/src/lib/elementary/efl_ui_collection.eo b/src/lib/elementary/efl_ui_collection.eo
new file mode 100644
index 0000000000..a3e302e320
--- /dev/null
+++ b/src/lib/elementary/efl_ui_collection.eo
@@ -0,0 +1,84 @@
+class @beta Efl.Ui.Collection extends Efl.Ui.Layout_Base implements
+ Efl.Ui.Scrollable_Interactive,
+ Efl.Ui.Scrollbar,
+ Efl.Pack_Linear, Efl.Pack_Layout,
+ Efl.Ui.Layout_Orientable,
+ Efl.Ui.Container_Selectable,
+ Efl.Ui.Multi_Selectable,
+ Efl.Ui.Focus.Manager_Sub,
+ Efl.Ui.Widget_Focus_Manager
+{
+ [[This widget displays a list of items in an arrangement controlled by an external $position_manager object. By using different $position_manager objects this widget can show lists of items or two-dimensional grids of items, for example.
+
+ Items inside this widget can be selected according to the $select_mode policy, and retrieved with $selected_items_get.
+ ]]
+ event_prefix:efl_ui;
+ methods {
+ item_scroll {
+ [[Bring the passed item into the viewport.]]
+ params {
+ @in item: Efl.Ui.Item; [[The target to move in.]]
+ @in animation: bool; [[If you want to have an animation or not.]]
+ }
+ }
+ item_scroll_align {
+ [[Bring the passed item into the viewport, place the item accordingly to align in the viewport.
+
+ $align selects the final position of the object inside the viewport. 0.0 will move the object to the first visible position inside the viewport, 1.0 will move it to the last visible position, and values in between will move it accordingly to positions in between, along the scrolling axis.
+ ]]
+ params {
+ @in item: Efl.Ui.Item; [[The target to move in.]]
+ @in align: double; [[0.0 to have this item at the upper or left side of the viewport, 1.0 to have this item at the lower or right side of the viewport]]
+ @in animation: bool; [[If you want to have an animation or not.]]
+ }
+ }
+ @property position_manager {
+ [[Position manager object that handles placement of items.]]
+ values {
+ position_manager : Efl.Ui.Position_Manager.Entity @owned; [[The objects ownership is passed to the item container.]]
+ }
+ }
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.finalize;
+ Efl.Object.destructor;
+ Efl.Object.invalidate;
+ Efl.Container.content_iterate;
+ Efl.Container.content_count;
+ Efl.Ui.Layout_Orientable.orientation { get; set; }
+ Efl.Ui.Widget.theme_apply;
+ Efl.Pack.pack_clear;
+ Efl.Pack.unpack_all;
+ Efl.Pack.unpack;
+ Efl.Pack.pack;
+ Efl.Pack_Linear.pack_end;
+ Efl.Pack_Linear.pack_begin;
+ Efl.Pack_Linear.pack_before;
+ Efl.Pack_Linear.pack_after;
+ Efl.Pack_Linear.pack_at;
+ Efl.Pack_Linear.pack_unpack_at;
+ Efl.Pack_Linear.pack_index_get;
+ Efl.Pack_Linear.pack_content_get;
+ Efl.Ui.Scrollable_Interactive.match_content { set; }
+ Efl.Ui.Widget_Focus_Manager.focus_manager_create;
+ Efl.Ui.Widget.focus_state_apply;
+ Efl.Ui.Focus.Manager.move;
+ Efl.Ui.Single_Selectable.last_selected { get; }
+ Efl.Ui.Multi_Selectable.selected_items_get;
+ Efl.Ui.Multi_Selectable.select_mode {get; set;}
+ }
+ events {
+ item,pressed : Efl.Ui.Item; [[A $press event occurred over an item.]]
+ item,unpressed : Efl.Ui.Item; [[A $unpress event occurred over an item.]]
+ item,longpressed : Efl.Ui.Item; [[A $longpressed event occurred over an item.]]
+ item,clicked : Efl.Ui.Item; [[A $clicked event occurred over an item.]]
+ item,clicked,any : Efl.Ui.Item; [[A $clicked,any event occurred over an item.]]
+ }
+ composite {
+ Efl.Ui.Scrollable_Interactive;
+ Efl.Ui.Scrollbar;
+ Efl.Ui.Focus.Manager;
+ }
+}
+
diff --git a/src/lib/elementary/efl_ui_collection_focus_manager.eo b/src/lib/elementary/efl_ui_collection_focus_manager.eo
new file mode 100644
index 0000000000..e015dea7c9
--- /dev/null
+++ b/src/lib/elementary/efl_ui_collection_focus_manager.eo
@@ -0,0 +1,7 @@
+class @beta Efl.Ui.Collection_Focus_Manager extends Efl.Ui.Focus.Manager_Calc {
+ [[Internal class which implements collection specific behaviour, cannot be used outside of collection]]
+ implements {
+ Efl.Ui.Focus.Manager.manager_focus { set; }
+ Efl.Ui.Focus.Manager.request_move;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_container_layout.c b/src/lib/elementary/efl_ui_container_layout.c
index 770e55a5dc..34a8bbb49b 100644
--- a/src/lib/elementary/efl_ui_container_layout.c
+++ b/src/lib/elementary/efl_ui_container_layout.c
@@ -53,7 +53,7 @@ _efl_ui_container_layout_item_init(Eo* o, Efl_Ui_Container_Item_Hints *item)
efl_gfx_hint_margin_get(o, &item[0].margin[0], &item[0].margin[1],
&item[1].margin[0], &item[1].margin[1]);
efl_gfx_hint_fill_get(o, &item[0].fill, &item[1].fill);
- max = efl_gfx_hint_size_max_get(o);
+ max = efl_gfx_hint_size_combined_max_get(o);
min = efl_gfx_hint_size_combined_min_get(o);
efl_gfx_hint_aspect_get(o, &aspect_type, &aspect);
item[0].aspect = aspect.w;
diff --git a/src/lib/elementary/efl_ui_datepicker.c b/src/lib/elementary/efl_ui_datepicker.c
index 810c9bc4c4..0a4a39b171 100644
--- a/src/lib/elementary/efl_ui_datepicker.c
+++ b/src/lib/elementary/efl_ui_datepicker.c
@@ -18,7 +18,7 @@
Efl_Time t = efl_datetime_manager_value_get(pd->dt_manager); \
pd->cur_date[DATEPICKER_YEAR] = t.tm_year + 1900; \
pd->cur_date[DATEPICKER_MONTH] = t.tm_mon + 1; \
- pd->cur_date[DATEPICKER_DAY] = t.tm_mday; \
+ pd->cur_date[DATEPICKER_DAY] = t.tm_mday + 1; \
} while (0)
#define DATE_SET() \
@@ -26,7 +26,7 @@
Efl_Time t; \
t.tm_year = pd->cur_date[DATEPICKER_YEAR] - 1900; \
t.tm_mon = pd->cur_date[DATEPICKER_MONTH] - 1; \
- t.tm_mday = pd->cur_date[DATEPICKER_DAY]; \
+ t.tm_mday = pd->cur_date[DATEPICKER_DAY] - 1; \
t.tm_sec = 0; \
efl_datetime_manager_value_set(pd->dt_manager, t); \
} while (0)
@@ -160,25 +160,25 @@ _fields_init(Eo *obj)
//Field create.
pd->year = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
- efl_ui_range_limits_set(efl_added, 1970, 2037),
- efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_range_limits_set(efl_added, 1900, 2037),
+ efl_ui_spin_button_wraparound_set(efl_added, EINA_TRUE),
efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL),
- efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj));
+ efl_event_callback_add(efl_added, EFL_UI_RANGE_EVENT_CHANGED,_field_changed_cb, obj));
pd->month = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
efl_ui_range_limits_set(efl_added, 1, 12),
- efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_spin_button_wraparound_set(efl_added, EINA_TRUE),
efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL),
- efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj));
+ efl_event_callback_add(efl_added, EFL_UI_RANGE_EVENT_CHANGED,_field_changed_cb, obj));
pd->day = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
efl_ui_range_limits_set(efl_added, 1, 31),
- efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_spin_button_wraparound_set(efl_added, EINA_TRUE),
efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL),
- efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj));
+ efl_event_callback_add(efl_added, EFL_UI_RANGE_EVENT_CHANGED,_field_changed_cb, obj));
DATE_GET();
//Using system config?
@@ -222,20 +222,6 @@ _fields_init(Eo *obj)
}
}
-EOLIAN static void
-_efl_ui_datepicker_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Datepicker_Data *_pd EINA_UNUSED)
-{
- Evas_Coord minw = -1, minh = -1;
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- edje_object_size_min_restricted_calc
- (wd->resize_obj, &minw, &minh, minw, minh);
- elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- evas_object_size_hint_min_set(obj, minw, minh);
- evas_object_size_hint_max_set(obj, -1, -1);
-}
-
EOLIAN static Eo *
_efl_ui_datepicker_efl_object_constructor(Eo *obj, Efl_Ui_Datepicker_Data *pd)
{
@@ -342,7 +328,4 @@ _efl_ui_datepicker_date_get(const Eo *obj EINA_UNUSED, Efl_Ui_Datepicker_Data *p
*day = pd->cur_date[DATEPICKER_DAY];
}
-#define EFL_UI_DATEPICKER_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_datepicker), \
-
#include "efl_ui_datepicker.eo.c"
diff --git a/src/lib/elementary/efl_ui_default_item.c b/src/lib/elementary/efl_ui_default_item.c
new file mode 100644
index 0000000000..3063cd164c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_default_item.c
@@ -0,0 +1,43 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_UI_LIST_DEFAULT_ITEM_PROTECTED
+#define EFL_PART_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "elm_part_helper.h"
+
+#define MY_CLASS EFL_UI_DEFAULT_ITEM_CLASS
+#define MY_CLASS_PFX efl_ui_default_item
+
+#define MY_CLASS_NAME "Efl.Ui.Default_Item"
+
+ELM_PART_TEXT_DEFAULT_GET(efl_ui_default_item, "efl.text")
+ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_default_item, void)
+ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_default_item, void)
+ELM_PART_CONTENT_DEFAULT_GET(efl_ui_default_item, "efl.icon")
+ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_default_item, void)
+
+EOLIAN static Efl_Object *
+_efl_ui_default_item_efl_part_part_get(const Eo *obj, void *pd EINA_UNUSED, const char *part)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
+ if (eina_streq(part, "text"))
+ return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_TEXT_CLASS, obj, "efl.text");
+ else if (eina_streq(part, "icon"))
+ return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.icon");
+ else if (eina_streq(part, "extra"))
+ return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.extra");
+
+ return efl_part_get(efl_super(obj, MY_CLASS), part);
+}
+
+
+#define EFL_UI_DEFAULT_ITEM_EXTRA_OPS \
+ ELM_PART_TEXT_DEFAULT_OPS(efl_ui_default_item), \
+ ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_default_item)
+
+#include "efl_ui_default_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_default_item.eo b/src/lib/elementary/efl_ui_default_item.eo
new file mode 100644
index 0000000000..374acc5de7
--- /dev/null
+++ b/src/lib/elementary/efl_ui_default_item.eo
@@ -0,0 +1,30 @@
+abstract @beta Efl.Ui.Default_Item extends Efl.Ui.Item implements
+ Efl.Text,
+ Efl.Text_Markup,
+ Efl.Ui.L10n,
+ Efl.Content
+{
+ [[Default Item Class.
+
+ This class defines the standard parts of casual efl items.
+ The details about placement or item layout preferences are left to the extending classes.
+ Every text property related changes are mirrored to the text part. Content changes are mirrored to the content part.
+
+ ]]
+ data: null;
+ parts {
+ text: Efl.Ui.Layout_Part_Text; [[The text part for default item.
+ text part is the caption of the item.]]
+ icon: Efl.Ui.Layout_Part_Content; [[The icon content part for default item.
+ icon part is the main content of item.]]
+ extra : Efl.Ui.Layout_Part_Content; [[The extra content part for default item.]]
+ }
+ implements {
+ Efl.Text.text { get; set; }
+ Efl.Text_Markup.markup { get; set; }
+ Efl.Ui.L10n.l10n_text { get; set; }
+ Efl.Content.content { get; set; }
+ Efl.Content.content_unset;
+ Efl.Part.part_get;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_flip.c b/src/lib/elementary/efl_ui_flip.c
index 23ce004d32..26f8d848bf 100644
--- a/src/lib/elementary/efl_ui_flip.c
+++ b/src/lib/elementary/efl_ui_flip.c
@@ -67,8 +67,8 @@ static void
_sizing_eval(Evas_Object *obj)
{
Evas_Coord minw = -1, minh = -1, minw2 = -1, minh2 = -1;
- Evas_Coord maxw = -1, maxh = -1, maxw2 = -1, maxh2 = -1;
int fingx = 0, fingy = 0;
+ Eina_Size2D max = EINA_SIZE2D(-1, -1), max2 = EINA_SIZE2D(-1, -1);
EFL_UI_FLIP_DATA_GET(obj, sd);
@@ -77,14 +77,14 @@ _sizing_eval(Evas_Object *obj)
if (sd->back.content)
evas_object_size_hint_combined_min_get(sd->back.content, &minw2, &minh2);
if (sd->front.content)
- evas_object_size_hint_max_get(sd->front.content, &maxw, &maxh);
+ max = efl_gfx_hint_size_combined_max_get(sd->front.content);
if (sd->back.content)
- evas_object_size_hint_max_get(sd->back.content, &maxw2, &maxh2);
+ max2 = efl_gfx_hint_size_combined_max_get(sd->back.content);
if (minw2 > minw) minw = minw2;
if (minh2 > minh) minh = minh2;
- if ((maxw2 >= 0) && (maxw2 < maxw)) maxw = maxw2;
- if ((maxh2 >= 0) && (maxh2 < maxh)) maxh = maxh2;
+ if ((max2.w >= 0) && (max2.w < max.w)) max.w = max2.w;
+ if ((max2.h >= 0) && (max2.h < max.h)) max.h = max2.h;
if (sd->dir_enabled[ELM_FLIP_DIRECTION_UP]) fingy++;
if (sd->dir_enabled[ELM_FLIP_DIRECTION_DOWN]) fingy++;
@@ -93,8 +93,8 @@ _sizing_eval(Evas_Object *obj)
elm_coords_finger_size_adjust(fingx, &minw, fingy, &minh);
- evas_object_size_hint_min_set(obj, minw, minh);
- evas_object_size_hint_max_set(obj, maxw, maxh);
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
+ efl_gfx_hint_size_restricted_max_set(obj, max);
}
EOLIAN static Eina_Error
diff --git a/src/lib/elementary/efl_ui_focus_layer.c b/src/lib/elementary/efl_ui_focus_layer.c
index 6c6c8218c1..ccbe1d31e8 100644
--- a/src/lib/elementary/efl_ui_focus_layer.c
+++ b/src/lib/elementary/efl_ui_focus_layer.c
@@ -55,10 +55,10 @@ _efl_ui_focus_layer_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Focus_Layer_Data *
}
EOLIAN static void
-_efl_ui_focus_layer_efl_object_destructor(Eo *obj, Efl_Ui_Focus_Layer_Data *pd EINA_UNUSED)
+_efl_ui_focus_layer_efl_object_invalidate(Eo *obj, Efl_Ui_Focus_Layer_Data *pd EINA_UNUSED)
{
efl_ui_focus_layer_enable_set(obj, EINA_FALSE);
- efl_destructor(efl_super(obj, MY_CLASS));
+ efl_invalidate(efl_super(obj, MY_CLASS));
}
EOLIAN static Efl_Ui_Focus_Manager*
diff --git a/src/lib/elementary/efl_ui_focus_layer.eo b/src/lib/elementary/efl_ui_focus_layer.eo
index fd177caf62..4773de3201 100644
--- a/src/lib/elementary/efl_ui_focus_layer.eo
+++ b/src/lib/elementary/efl_ui_focus_layer.eo
@@ -28,6 +28,6 @@ mixin @beta Efl.Ui.Focus.Layer requires Efl.Ui.Widget extends Efl.Ui.Widget_Focu
Efl.Ui.Focus.Object.focus_manager { get; }
Efl.Ui.Focus.Object.focus_parent { get; }
Efl.Object.constructor;
- Efl.Object.destructor;
+ Efl.Object.invalidate;
}
}
diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c
index 29b52f2eb6..fa26b515e0 100644
--- a/src/lib/elementary/efl_ui_focus_manager_calc.c
+++ b/src/lib/elementary/efl_ui_focus_manager_calc.c
@@ -68,6 +68,8 @@ struct _Node{
} graph;
Eina_Bool on_list : 1;
+ Eina_Bool unused : 1;
+ Eina_Bool this_is_root : 1;
};
#define T(n) (n->tree)
@@ -85,6 +87,19 @@ typedef struct {
Node *root;
} Efl_Ui_Focus_Manager_Calc_Data;
+static Eina_Mempool *_node_mempool;
+
+static Node*
+node_mem_get(void)
+{
+ return eina_mempool_calloc(_node_mempool, sizeof(Node));
+}
+
+static void
+node_mem_free(Node *n)
+{
+ eina_mempool_free(_node_mempool, n);
+}
static Node* _request_subchild(Node *node);
static void dirty_add(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Node *dirty);
@@ -195,7 +210,7 @@ node_new(Efl_Ui_Focus_Object *focusable, Efl_Ui_Focus_Manager *manager)
{
Node *node;
- node = calloc(1, sizeof(Node));
+ node = node_mem_get();
node->focusable = focusable;
node->manager = manager;
@@ -237,42 +252,49 @@ node_item_free(Node *item)
/*cleanup graph parts*/
//add all neighbors of the node to the dirty list
- for(int i = EFL_UI_FOCUS_DIRECTION_UP; i < EFL_UI_FOCUS_DIRECTION_LAST; i++)
+ if (!item->unused)
{
- Node *partner;
+ for(int i = EFL_UI_FOCUS_DIRECTION_UP; i < EFL_UI_FOCUS_DIRECTION_LAST; i++)
+ {
+ Node *partner;
#define MAKE_LIST_DIRTY(node, field) \
- EINA_LIST_FOREACH(DIRECTION_ACCESS(node, i).field, l, partner) \
- { \
- if (partner->type != NODE_TYPE_ONLY_LOGICAL) \
+ EINA_LIST_FOREACH(DIRECTION_ACCESS(node, i).field, l, partner) \
{ \
- dirty_add(obj, pd, partner); \
- dirty_added = EINA_TRUE; \
- } \
- }
+ if (partner->type != NODE_TYPE_ONLY_LOGICAL) \
+ { \
+ dirty_add(obj, pd, partner); \
+ dirty_added = EINA_TRUE; \
+ } \
+ }
+
+ MAKE_LIST_DIRTY(item, one_direction)
+ MAKE_LIST_DIRTY(item, cleanup_nodes)
- MAKE_LIST_DIRTY(item, one_direction)
- MAKE_LIST_DIRTY(item, cleanup_nodes)
+ border_onedirection_cleanup(item, i);
+ border_onedirection_set(item, i, NULL);
+ }
- border_onedirection_cleanup(item, i);
- border_onedirection_set(item, i, NULL);
}
//the unregistering of a item should ever result in atleast a coords_dirty call
- if (!dirty_added)
+ if (dirty_added)
efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, NULL);
/*cleanup manager householdings*/
//remove from the focus stack
- pd->focus_stack = eina_list_remove(pd->focus_stack, item);
+
+ if (!item->unused)
+ pd->focus_stack = eina_list_remove(pd->focus_stack, item);
//if this is the entry for redirect, NULL them out!
if (pd->redirect_entry == item->focusable)
pd->redirect_entry = NULL;
//remove from the dirty parts
- pd->dirty = eina_list_remove(pd->dirty, item);
+ if (item->on_list)
+ pd->dirty = eina_list_remove(pd->dirty, item);
item->on_list = EINA_FALSE;
/*merge tree items*/
@@ -307,7 +329,7 @@ node_item_free(Node *item)
//free the safed order
ELM_SAFE_FREE(T(item).saved_order, eina_list_free);
- free(item);
+ node_mem_free(item);
}
//FOCUS-STACK HELPERS
@@ -375,7 +397,7 @@ dirty_flush_node(Efl_Ui_Focus_Manager *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Cal
Efl_Ui_Focus_Graph_Calc_Result result;
efl_ui_focus_graph_calc(&pd->graph_ctx, eina_iterator_filter_new(eina_hash_iterator_data_new(pd->node_hash), _no_logical, NULL, NULL) , (Opaque_Graph_Member*) node, &result);
-
+ node->unused = EINA_FALSE;
for (int i = 0; i < 4; ++i)
{
Efl_Ui_Focus_Direction direction = -1;
@@ -506,7 +528,7 @@ _register(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *chil
node = node_new(child, obj);
eina_hash_add(pd->node_hash, &child, node);
-
+ node->unused = EINA_TRUE;
//add the parent
if (parent)
{
@@ -878,14 +900,13 @@ static void
_free_node(void *data)
{
Node *node = data;
- FOCUS_DATA(node->manager);
if (node->type == NODE_TYPE_ONLY_LOGICAL)
efl_event_callback_array_del(node->focusable, logical_node(), node->manager);
else
efl_event_callback_array_del(node->focusable, regular_node(), node->manager);
- if (pd->root != data)
+ if (!node->this_is_root)
{
node_item_free(node);
}
@@ -1496,6 +1517,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U
//make sure this manager is in the chain of redirects
_manager_in_chain_set(obj, pd);
+ node->unused = EINA_FALSE;
node_type = node->type;
new_focusable = node->focusable;
@@ -1508,6 +1530,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U
//remove the object from the list and add it again
if (node_type == NODE_TYPE_NORMAL)
{
+ EINA_SAFETY_ON_TRUE_RETURN(node->unused);
pd->focus_stack = eina_list_remove(pd->focus_stack, node);
pd->focus_stack = eina_list_append(pd->focus_stack, node);
}
@@ -1736,6 +1759,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_root_set(Eo *obj EINA_UNUSED, Ef
node = _register(obj, pd, root, NULL, NODE_TYPE_ONLY_LOGICAL, NULL);
pd->root = node;
+ pd->root->this_is_root = 1;
return EINA_TRUE;
}
@@ -1833,6 +1857,20 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_fetch(Eo *obj, Efl_Ui_Focus_Mana
EOLIAN static void
_efl_ui_focus_manager_calc_class_constructor(Efl_Class *c EINA_UNUSED)
{
+ const char *choice, *tmp;
+
+#ifdef EINA_DEFAULT_MEMPOOL
+ choice = "pass_through";
+#else
+ choice = "chained_mempool";
+#endif
+ tmp = getenv("EINA_MEMPOOL");
+ if (tmp && tmp[0])
+ choice = tmp;
+
+ _node_mempool = eina_mempool_add
+ (choice, "Focus-Node mempool", NULL, sizeof(Node), 20);
+
_focus_log_domain = eina_log_domain_register("elementary-focus", EINA_COLOR_CYAN);
}
diff --git a/src/lib/elementary/efl_ui_focus_manager_root_focus.c b/src/lib/elementary/efl_ui_focus_manager_root_focus.c
index f47fe3d3fe..29507001fb 100644
--- a/src/lib/elementary/efl_ui_focus_manager_root_focus.c
+++ b/src/lib/elementary/efl_ui_focus_manager_root_focus.c
@@ -19,8 +19,22 @@ typedef struct {
Eina_Bool rect_registered;
Eina_List *iterator_list;
+ Eina_Future *focus_transfer;
} Efl_Ui_Focus_Manager_Root_Focus_Data;
+static Eina_Value
+_unregister_rect(Eo *obj, void *data EINA_UNUSED, const Eina_Value v EINA_UNUSED)
+{
+ Efl_Ui_Focus_Manager_Root_Focus_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+
+ efl_ui_focus_manager_calc_unregister(obj, pd->rect);
+ pd->rect_registered = EINA_FALSE;
+ efl_ui_focus_composition_adapter_focus_manager_parent_set(pd->rect, NULL);
+ efl_ui_focus_composition_adapter_focus_manager_object_set(pd->rect, NULL);
+ pd->focus_transfer = NULL;
+ return EINA_VALUE_EMPTY;
+}
+
static Efl_Ui_Focus_Object*
_trap(Efl_Ui_Focus_Manager_Root_Focus_Data *pd, Efl_Ui_Focus_Object *obj)
{
@@ -46,15 +60,17 @@ _state_eval(Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd)
if (sub && pd->rect_registered)
{
- efl_ui_focus_manager_calc_unregister(obj, pd->rect);
- pd->rect_registered = EINA_FALSE;
- efl_ui_focus_composition_adapter_focus_manager_parent_set(pd->rect, NULL);
- efl_ui_focus_composition_adapter_focus_manager_object_set(pd->rect, NULL);
+ pd->focus_transfer = efl_loop_job(efl_main_loop_get());
+ efl_future_then(obj, pd->focus_transfer, _unregister_rect);
}
else if (!sub && !pd->rect_registered)
{
Efl_Ui_Focus_Object *root;
+ if (pd->focus_transfer)
+ eina_future_cancel(pd->focus_transfer);
+ pd->focus_transfer = NULL;
+
root = efl_ui_focus_manager_root_get(obj);
efl_ui_focus_manager_calc_register(obj, pd->rect, root, NULL);
efl_ui_focus_composition_adapter_focus_manager_parent_set(pd->rect, root);
diff --git a/src/lib/elementary/efl_ui_focus_parent_provider_gen.c b/src/lib/elementary/efl_ui_focus_parent_provider_gen.c
index 1ad1ab2ae1..cb6700cdd6 100644
--- a/src/lib/elementary/efl_ui_focus_parent_provider_gen.c
+++ b/src/lib/elementary/efl_ui_focus_parent_provider_gen.c
@@ -37,6 +37,10 @@ _efl_ui_focus_parent_provider_gen_container_set(Eo *obj, Efl_Ui_Focus_Parent_Pro
EINA_SAFETY_ON_NULL_RETURN(efl_parent_get(pd->container));
pd->provider = efl_provider_find(efl_parent_get(pd->container), EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE);
+
+ ELM_WIDGET_DATA_GET(pd->container, wid_pd);
+
+ ((Efl_Ui_Shared_Win_Data*)wid_pd->shared_win_data)->custom_parent_provider = EINA_TRUE;
}
EOLIAN static Efl_Ui_Widget*
diff --git a/src/lib/elementary/efl_ui_focus_util.eo b/src/lib/elementary/efl_ui_focus_util.eo
index c19c05cb18..40b38a540e 100644
--- a/src/lib/elementary/efl_ui_focus_util.eo
+++ b/src/lib/elementary/efl_ui_focus_util.eo
@@ -1,20 +1,20 @@
class @beta Efl.Ui.Focus.Util extends Efl.Object {
[[EFL UI Focus Util class]]
methods {
- focus @class {
+ focus @static {
[[Focus helper method]]
params {
focus_elem : Efl.Ui.Focus.Object; [[Focus element]]
}
}
- active_manager @class {
+ active_manager @static {
[[Get the highest manager in the redirect property]]
params {
manager : Efl.Ui.Focus.Manager;
}
return: Efl.Ui.Focus.Manager;
}
- direction_complement @class {
+ direction_complement @static {
params {
dir : Efl.Ui.Focus.Direction;
}
diff --git a/src/lib/elementary/efl_ui_format.c b/src/lib/elementary/efl_ui_format.c
index beb3945f43..2dff332409 100644
--- a/src/lib/elementary/efl_ui_format.c
+++ b/src/lib/elementary/efl_ui_format.c
@@ -264,10 +264,10 @@ _efl_ui_format_formatted_value_get(Eo *obj EINA_UNUSED, Efl_Ui_Format_Data *pd,
if (pd->format_values)
{
/* Search in the format_values array if we have one */
- Efl_Ui_Format_Value v = { 0 };
+ Efl_Ui_Format_Value val = { 0 };
int ndx;
- eina_value_int_convert(&value, &v.value);
- ndx = eina_inarray_search_sorted(pd->format_values, &v, (Eina_Compare_Cb)_value_compare);
+ eina_value_int_convert(&value, &val.value);
+ ndx = eina_inarray_search_sorted(pd->format_values, &val, (Eina_Compare_Cb)_value_compare);
if (ndx > -1) {
Efl_Ui_Format_Value *entry = eina_inarray_nth(pd->format_values, ndx);
eina_strbuf_append(str, entry->text);
diff --git a/src/lib/elementary/efl_ui_frame.c b/src/lib/elementary/efl_ui_frame.c
index fd9420d6b7..0e6f230d5b 100644
--- a/src/lib/elementary/efl_ui_frame.c
+++ b/src/lib/elementary/efl_ui_frame.c
@@ -5,7 +5,7 @@
#define EFL_ACCESS_OBJECT_PROTECTED
#define ELM_LAYOUT_PROTECTED
#define EFL_PART_PROTECTED
-#define EFL_UI_CLICKABLE_PROTECTED
+#define EFL_INPUT_CLICKABLE_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"
@@ -38,14 +38,17 @@ _sizing_eval(Evas_Object *obj,
evas_object_size_hint_min_get(obj, &cminw, &cminh);
if ((minw == cminw) && (minh == cminh)) return;
- evas_object_size_hint_min_set(obj, minw, minh);
- evas_object_size_hint_max_set(obj, -1, -1);
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
+ if (elm_widget_is_legacy(obj))
+ evas_object_size_hint_max_set(obj, -1, -1);
+ else
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
}
static void
_recalc(void *data, const Efl_Event *event EINA_UNUSED)
{
- elm_layout_sizing_eval(data);
+ efl_canvas_group_calculate(data);
}
static void
@@ -61,7 +64,7 @@ _on_recalc_done(void *data,
(wd->resize_obj, EFL_LAYOUT_EVENT_RECALC, _recalc, data);
sd->anim = EINA_FALSE;
- elm_layout_sizing_eval(data);
+ efl_canvas_group_calculate(data);
}
static void
@@ -95,14 +98,9 @@ _on_frame_clicked(void *data,
EOLIAN static void
_efl_ui_frame_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Frame_Data *sd)
{
- EFL_UI_LAYOUT_DATA_GET(obj, ld);
-
- if (ld->needs_size_calc)
- {
- /* calling OWN sizing evaluate code here */
- _sizing_eval(obj, sd);
- ld->needs_size_calc = EINA_FALSE;
- }
+ /* calling OWN sizing evaluate code here */
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
+ _sizing_eval(obj, sd);
}
static void
@@ -147,8 +145,8 @@ _efl_ui_frame_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Frame_Data *_pd EINA_UN
edje_object_signal_callback_add
(wd->resize_obj, "efl,anim,done", "efl",
_on_recalc_done, obj);
- efl_ui_clickable_util_bind_to_theme(wd->resize_obj, obj);
- efl_event_callback_add(obj, EFL_UI_EVENT_CLICKED, _clicked_cb, obj);
+ efl_ui_action_connector_bind_clickable_to_theme(wd->resize_obj, obj);
+ efl_event_callback_add(obj, EFL_INPUT_EVENT_CLICKED, _clicked_cb, obj);
}
elm_widget_can_focus_set(obj, EINA_FALSE);
@@ -158,8 +156,6 @@ _efl_ui_frame_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Frame_Data *_pd EINA_UN
elm_widget_theme_element_get(obj),
elm_widget_theme_style_get(obj)) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
CRI("Failed to set layout!");
-
- elm_layout_sizing_eval(obj);
}
EOLIAN static Eo *
diff --git a/src/lib/elementary/efl_ui_frame.eo b/src/lib/elementary/efl_ui_frame.eo
index 509bd02df0..31849f95d7 100644
--- a/src/lib/elementary/efl_ui_frame.eo
+++ b/src/lib/elementary/efl_ui_frame.eo
@@ -1,4 +1,4 @@
-class @beta Efl.Ui.Frame extends Efl.Ui.Layout_Base implements Efl.Ui.Clickable, Efl.Text, Efl.Text_Markup,
+class @beta Efl.Ui.Frame extends Efl.Ui.Layout_Base implements Efl.Input.Clickable, Efl.Text, Efl.Text_Markup,
Efl.Content
{
[[Frame widget
diff --git a/src/lib/elementary/efl_ui_frame_legacy_eo.c b/src/lib/elementary/efl_ui_frame_legacy_eo.c
index 22e40576a2..ca10f87b8a 100644
--- a/src/lib/elementary/efl_ui_frame_legacy_eo.c
+++ b/src/lib/elementary/efl_ui_frame_legacy_eo.c
@@ -32,4 +32,4 @@ static const Efl_Class_Description _efl_ui_frame_legacy_class_desc = {
NULL
};
-EFL_DEFINE_CLASS(efl_ui_frame_legacy_class_get, &_efl_ui_frame_legacy_class_desc, EFL_UI_FRAME_CLASS, EFL_UI_LEGACY_INTERFACE, NULL);
+EFL_DEFINE_CLASS(efl_ui_frame_legacy_class_get, &_efl_ui_frame_legacy_class_desc, EFL_UI_FRAME_CLASS, ELM_LAYOUT_MIXIN, EFL_UI_LEGACY_INTERFACE, NULL);
diff --git a/src/lib/elementary/efl_ui_grid.c b/src/lib/elementary/efl_ui_grid.c
index 20ef53d2f1..226b3780cb 100644
--- a/src/lib/elementary/efl_ui_grid.c
+++ b/src/lib/elementary/efl_ui_grid.c
@@ -6,1128 +6,23 @@
#define EFL_UI_SCROLL_MANAGER_PROTECTED
#define EFL_UI_SCROLLBAR_PROTECTED
-#include <Elementary.h>
+#include <Efl_Ui.h>
#include "elm_priv.h"
-#include "efl_ui_grid_private.h"
#include "efl_ui_item_private.h"
-#include "efl_ui_grid_item_private.h"
#define MY_CLASS EFL_UI_GRID_CLASS
#define MY_CLASS_PFX efl_ui_grid
#define MY_CLASS_NAME "Efl.Ui.Grid"
-static void _grid_clear_internal(Eo *obj, Efl_Ui_Grid_Data *pd);
-static void _grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *item);
-
-static int
-clamp_index(Efl_Ui_Grid_Data *pd, int index)
-{
- if (index < ((int)eina_list_count(pd->items)) * -1)
- return -1;
- else if (index > (int)eina_list_count(pd->items) - 1)
- return 1;
- return 0;
-}
-
-static int
-index_adjust(Efl_Ui_Grid_Data *pd, int index)
-{
- int c = eina_list_count(pd->items);
- if (index < c * -1)
- return 0;
- else if (index > c - 1)
- return c - 1;
- else if (index < 0)
- return index + c;
- return index;
-}
-
-static void
-_need_update(Efl_Ui_Grid_Data *pd)
-{
- pd->need_update = EINA_TRUE;
- //group_calculate call
- efl_canvas_group_change(pd->obj);
-}
-
-static void
-_relayout(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
-{
- Eina_List *l;
- Efl_Ui_Grid_Item *item;
- Efl_Ui_Grid_Item_Data *prev;
- Eina_Position2D ipos;
- Eina_Position2D cur = {0, 0};
- int outer;
- int count = 0;
- Eina_Bool horiz = 0;
- Eina_Size2D min, max;
-
- if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL) horiz = 1;
-
- if (!pd->linemax)
- {
- pd->linemax =(horiz ?
- ((pd->geo.h + pd->item.pad.h) / (pd->item.size.h + pd->item.pad.h)) :
- ((pd->geo.w + pd->item.pad.w) / (pd->item.size.w + pd->item.pad.w)));
- if (!pd->linemax) pd->linemax = 1;
- }
-
-
- outer = (horiz ?
- (pd->geo.h + pd->item.pad.h) - (pd->linemax * (pd->item.size.h + pd->item.pad.h)) :
- (pd->geo.w + pd->item.pad.w) - (pd->linemax * (pd->item.size.w + pd->item.pad.w)));
- // outer left top
- outer = (horiz ? (outer * pd->item.align.h) : (outer * pd->item.align.w));
- outer = (horiz ? (outer + pd->geo.y) : (outer + pd->geo.x));
-
- // Block?
- EINA_LIST_FOREACH(pd->items, l, item)
- {
- EFL_UI_GRID_ITEM_DATA_GET(item, id);
-
- if (pd->need_update || (id && (id->update_me || id->update_begin)))
- {
- // Index begin with zero value :
- id->index = count;
- if (id->update_me) id->update_me = EINA_FALSE;
- if (id->update_begin)
- {
- id->update_begin = EINA_FALSE;
- pd->need_update = EINA_TRUE;
- }
- if (horiz)
- {
- id->pos.row = (count % pd->linemax);
- id->pos.col = (count / pd->linemax);
- //Next Line
- if (count == 0)
- {
- cur.x = pd->geo.x;
- cur.y = outer;
- }
- else if (id->pos.row == 0)// ((cur.y + pd->item.pad.h + pd->item.size.h) > pd->geo.h)
- {
- cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
- cur.y = outer;
- }
- else
- {
- //cur.x = cur.x;
- cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
- }
- }
- else
- {
- id->pos.row = (count / pd->linemax);
- id->pos.col = (count % pd->linemax);
- //Next Line
- if (count == 0)
- {
- cur.x = outer;
- cur.y = pd->geo.y;
- }
- else if (id->pos.col == 0)//((cur.x + pd->item.pad.w + pd->item.size.w) > pd->geo.w)
- {
- cur.x = outer;
- cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
- }
- else
- {
- cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
- //cur.y = cur.y;
- }
- }
-
- min = efl_gfx_hint_size_min_get(item);
- max = efl_gfx_hint_size_max_get(item);
-
- if (pd->item.size.w < min.w) pd->item.size.w = min.w;
- if (pd->item.size.h < min.h) pd->item.size.h = min.h;
- if ((max.w > 0) && pd->item.size.w > max.w) pd->item.size.w = max.w;
- if ((max.h > 0) && pd->item.size.h > max.h) pd->item.size.h = max.h;
-
- id->geo.x = cur.x;
- id->geo.y = cur.y;
- id->geo.w = pd->item.size.w;
- id->geo.h = pd->item.size.h;
-
-
- }
-
- ipos.x = id->geo.x - pan.x;
- ipos.y = id->geo.y - pan.y;
-
- //
- efl_gfx_entity_position_set(item, ipos);
- efl_gfx_entity_size_set(item, id->geo.size);
- //efl_gfx_hint_size_restricted_min_set(item, id->geo.size);
-
- prev = id;
- count++;
- }
-
- if (horiz)
- pd->geo.w = cur.x + pd->item.size.w + pd->item.pad.w - pd->geo.x;
- else
- pd->geo.h = cur.y + pd->item.size.h + pd->item.pad.h - pd->geo.y;
-
- //efl_gfx_hint_size_restricted_min_set(pd->content, pd->geo.size);
- efl_gfx_entity_size_set(pd->content, pd->geo.size);
-
- pd->need_update = EINA_FALSE;
-}
-
-static void
-_reposition(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
-{
- Efl_Ui_Grid_Item *item;
- Eina_List *l;
- Eina_Position2D ipos;
-
- // Block?
- EINA_LIST_FOREACH(pd->items, l, item)
- {
- EFL_UI_GRID_ITEM_DATA_GET(item, id);
- if (!id) continue;
-
- ipos.x = id->geo.x - pan.x;
- ipos.y = id->geo.y - pan.y;
- efl_gfx_entity_position_set(item, ipos);
- efl_gfx_entity_size_set(item, id->geo.size);
- //efl_gfx_hint_size_min_set(item, id->geo.size);
- }
-
-}
-
-//Need to reimplements for grid
-static void
-_item_scroll_internal(Eo *obj,
- Efl_Ui_Grid_Item *item,
- double align,
- Eina_Bool anim)
-{
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- Eina_Rect ipos, view;
- Eina_Position2D vpos;
-
- if (!pd->smanager) return;
-
- ipos = efl_gfx_entity_geometry_get(item);
- view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
- vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
-
- if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL)
- {
- ipos.y = view.y;
- //ipos.h = ipos.h;
-
- // FIXME: align case will not correctly show in the position because of
- // bar size calculation. there are no certain way to know the scroll calcuation finished.
- if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
- {
- ipos.x = ipos.x + vpos.x - view.x;
- //ipos.w = ipos.w;
- }
- else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
- (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
- {
- ipos.x = ipos.x + vpos.x - view.x - (int)((view.w - ipos.w) * align);
- ipos.w = view.w;
- }
- else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
-
- }
- else //VERTICAL
- {
- ipos.x = view.x;
- //ipos.w = ipos.w;
-
- // FIXME: align case will not correctly show in the position because of
- // bar size calculation. there are no certain way to know the scroll calcuation finished.
- if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
- {
- ipos.y = ipos.y + vpos.y - view.y;
- //ipos.h = ipos.h;
- }
- else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
- (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
- {
- ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align);
- ipos.h = view.h;
- }
- else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
- }
-
- efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
-}
-
-static void
-_efl_ui_grid_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
-{
- Eo *obj = data;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- double width = 0.0, height = 0.0;
-
- edje_object_calc_force(wd->resize_obj);
- efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height);
- edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
- edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
-}
-
-static void
-_efl_ui_grid_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
-{
- Eo *obj = data;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- double posx = 0.0, posy = 0.0;
-
- efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy);
- edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
- edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
-}
-
-static void
-_efl_ui_grid_bar_show_cb(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
-
- if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
- else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
-}
-
-static void
-_efl_ui_grid_bar_hide_cb(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
-
- if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
- else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
-}
-
-static void
-_efl_ui_grid_content_moved_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- Eo *obj = data;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- if (!pd->smanager) return;
-
- efl_canvas_group_change(pd->obj);
-}
-
-static void
-_efl_ui_grid_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- Eo *obj = data;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- if (!pd->smanager) return;
-
- //reset linemax for recalculate layout.
- pd->linemax = 0;
-
- _need_update(pd);
- elm_layout_sizing_eval(obj);
-
- pd->pan_resized = EINA_TRUE;
-}
-
-static void
-_efl_ui_grid_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- elm_layout_sizing_eval(data);
-}
-
-static void
-_efl_ui_grid_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- elm_layout_sizing_eval(data);
-}
-
EOLIAN static Eo *
-_efl_ui_grid_efl_object_constructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
+_efl_ui_grid_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
- return obj;
-}
-
-EOLIAN static Eo *
-_efl_ui_grid_efl_object_finalize(Eo *obj,
- Efl_Ui_Grid_Data *pd)
-{
- pd->obj = obj = efl_finalize(efl_super(obj, MY_CLASS));
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
-
- efl_ui_layout_theme_set(obj, "grid", "base", efl_ui_widget_style_get(obj));
-
- pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
- efl_composite_attach(obj, pd->smanager);
- efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
-
- pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
-
- efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
- edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan);
-
- pd->select_mode = EFL_UI_SELECT_MODE_SINGLE;
-
- if ((pd->item.size.w == 0) && (pd->item.size.h == 0))
- {
- pd->item.size.w = 1;
- pd->item.size.h = 1;
- }
-
- efl_ui_scroll_connector_bind(obj, pd->smanager);
-
- //FIXME: Workaround code! fake Content for pan resize.
- // to remove this code, we need to customize pan class.
- pd->content = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(obj));
- efl_gfx_color_set(pd->content, 0, 0, 0, 0);
- efl_content_set(pd->pan, pd->content);
-
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
- _efl_ui_grid_bar_size_changed_cb, obj);
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
- _efl_ui_grid_bar_pos_changed_cb, obj);
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
- _efl_ui_grid_bar_show_cb, obj);
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
- _efl_ui_grid_bar_hide_cb, obj);
- efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_grid_resized_cb, obj);
- efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
- _efl_ui_grid_size_hint_changed_cb, obj);
- efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_grid_pan_resized_cb, obj);
- efl_event_callback_add(pd->content, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED,
- _efl_ui_grid_content_moved_cb, obj);
-
- elm_layout_sizing_eval(obj);
+ efl_ui_collection_position_manager_set(obj, efl_new(EFL_UI_POSITION_MANAGER_GRID_CLASS));
return obj;
}
-
-EOLIAN static void
-_efl_ui_grid_efl_object_invalidate(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- efl_ui_scroll_connector_unbind(obj);
-
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
- _efl_ui_grid_bar_size_changed_cb, obj);
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
- _efl_ui_grid_bar_pos_changed_cb, obj);
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
- _efl_ui_grid_bar_show_cb, obj);
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
- _efl_ui_grid_bar_hide_cb, obj);
- efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_grid_resized_cb, obj);
- efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
- _efl_ui_grid_size_hint_changed_cb, obj);
- efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_grid_pan_resized_cb, obj);
- efl_event_callback_del(pd->content, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED,
- _efl_ui_grid_content_moved_cb, obj);
- _grid_clear_internal(obj, pd);
-
- if (pd->smanager) efl_del(pd->smanager);
- pd->smanager = NULL;
- if (pd->content) efl_del(pd->content);
- pd->content = NULL;
- if (pd->pan) efl_del(pd->pan);
- pd->pan = NULL;
-
- efl_invalidate(efl_super(obj, MY_CLASS));
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_object_destructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
-{
- efl_destructor(efl_super(obj, MY_CLASS));
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
-
- Eina_Position2D pos = efl_ui_scrollable_content_pos_get(pd->smanager);
- Eina_Rect geo = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
-
- //ERR("pos[%d,%d], geo[%d,%d,%d,%d]", pos.x, pos.y, geo.x, geo.y, geo.w, geo.h);
-
- if (geo.w <= 1 || geo.h <= 1) return;
- // Need to be implemented
- if (pd->need_update)
- {
- _relayout(obj, pd, pos);
- }
- else
- {
- if (pd->pre_pos.x != pos.x || pd->pre_pos.y != pos.y)
- {
- _reposition(obj, pd, pos);
- }
- }
-
- pd->pre_pos = pos;
-
- if (pd->pan_resized)
- {
- pd->pan_resized = EINA_FALSE;
- // FIXME: Below code is workaround size check
- if ((geo.h > 1) && (pd->scroll.item))
- {
- _item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim);
-
- pd->scroll.item = NULL;
- pd->scroll.align = 0.0;
- pd->scroll.anim = EINA_FALSE;
- return;
- }
- }
-
- efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
-}
-
-EOLIAN static void
-_efl_ui_grid_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1};
- Eina_Rect view = {};
- Evas_Coord vmw = 0, vmh = 0;
- double xw = 0.0, yw = 0.0;
-
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
-
- min = efl_gfx_hint_size_combined_min_get(obj);
- max = efl_gfx_hint_size_max_get(obj);
- efl_gfx_hint_weight_get(obj, &xw, &yw);
-
- if (pd->smanager)
- view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
-
- if (xw > 0.0)
- {
- if ((min.w > 0) && (view.w < min.w))
- view.w = min.w;
- else if ((max.w > 0) && (view.w > max.w))
- view.w = max.w;
- }
- else if (min.w > 0)
- view.w = min.w;
-
- if (yw > 0.0)
- {
- if ((min.h > 0) && (view.h < min.h))
- view.h = min.h;
- else if ((max.h > 0) && (view.h > max.h))
- view.h = max.h;
- }
- else if (min.h > 0)
- view.h = min.h;
-
- edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
-
- if (pd->match_content_w) size.w = vmw + min.w;
- if (pd->match_content_h) size.h = vmh + min.h;
-
- max = efl_gfx_hint_size_max_get(obj);
- if ((max.w > 0) && (size.w > max.w)) size.w = max.w;
- if ((max.h > 0) && (size.h > max.h)) size.h = max.h;
- pd->geo = view;
- efl_gfx_hint_size_min_set(obj, size);
-
- _need_update(pd);
- return;
-}
-
-EOLIAN static int
-_efl_ui_grid_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
-{
- return eina_list_count(pd->items);
-}
-
-static Eina_Bool
-_grid_item_iterator_next(Item_Iterator *it, void **data)
-{
- Efl_Ui_Grid_Item *item;
-
- if (!eina_iterator_next(it->real_iterator, (void **)&item))
- return EINA_FALSE;
-
- if (data) *data = item;
- return EINA_TRUE;
-}
-
-static Eo *
-_grid_item_iterator_get_container(Item_Iterator *it)
-{
- return it->object;
-}
-
-static void
-_grid_item_iterator_free(Item_Iterator *it)
-{
- eina_iterator_free(it->real_iterator);
- eina_list_free(it->list);
- free(it);
-}
-
-static Eina_Iterator *
-_grid_item_iterator_new(Eo *obj, Eina_List *list)
-{
- // NEED-TO-IMPLEMENTS
- Item_Iterator *item;
-
- item = calloc(1, sizeof(*item));
- if (!item) return NULL;
-
- EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR);
-
- item->list = eina_list_clone(list);
- item->real_iterator = eina_list_iterator_new(item->list);
- item->iterator.version = EINA_ITERATOR_VERSION;
- item->iterator.next = FUNC_ITERATOR_NEXT(_grid_item_iterator_next);
- item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_grid_item_iterator_get_container);
- item->iterator.free = FUNC_ITERATOR_FREE(_grid_item_iterator_free);
- item->object = obj;
-
- return &item->iterator;
-}
-
-EOLIAN static Eina_Iterator *
-_efl_ui_grid_efl_container_content_iterate(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- return _grid_item_iterator_new(obj, pd->items);
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_ui_layout_orientable_orientation_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Efl_Ui_Layout_Orientation dir)
-{
- //FIXME: Currently only support horizontal and vertical mode.
- switch (dir)
- {
- case EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL:
- pd->dir = EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
- break;
- case EFL_UI_LAYOUT_ORIENTATION_VERTICAL:
- case EFL_UI_LAYOUT_ORIENTATION_DEFAULT:
- default:
- pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
- break;
- }
-
- pd->linemax = 0;
- efl_pack_layout_request(obj);
-}
-
-EOLIAN static Efl_Ui_Layout_Orientation
-_efl_ui_grid_efl_ui_layout_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
-{
- return pd->dir;
-}
-
-
-EOLIAN static Eina_Error
-_efl_ui_grid_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
- int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
- if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
-
- efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
-
- elm_layout_sizing_eval(obj);
-
- return int_ret;
-}
-
-static void
-_grid_item_pressed(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_Grid_Item *item = event->object;
- efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item);
-}
-
-static void
-_grid_item_unpressed(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_Grid_Item *item = event->object;
- efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item);
-}
-
-static void
-_grid_item_longpressed(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_Grid_Item *item = event->object;
- efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item);
-}
-
-static void
-_grid_item_selected(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_Grid_Item *item = event->object;
- Efl_Ui_Grid_Item *selected;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
-
- /* Single Select */
- if (pd->select_mode != EFL_UI_SELECT_MODE_MULTI)
- {
- EINA_LIST_FREE(pd->selected, selected)
- {
- if (selected != item)
- efl_ui_item_selected_set(selected, EINA_FALSE);
- }
- }
- pd->selected = eina_list_append(pd->selected, item);
- pd->last_selected = item;
-
- efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_SELECTED, item);
-}
-
-static void
-_grid_item_unselected(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_Grid_Item *item = event->object;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
-
- pd->selected = eina_list_remove(pd->selected, item);
- if (pd->last_selected == item) pd->last_selected = NULL;
-
- efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_UNSELECTED, item);
-}
-
-static void
-_grid_item_deleted(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_Grid_Item *it = event->object;
- EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
- _grid_item_unpack_internal(obj, pd, it);
-}
-
-static Eina_Bool
-_grid_item_process(Eo *obj, Efl_Ui_Grid_Data *pd, EINA_UNUSED Efl_Ui_Grid_Item *it)
-{
- if (!efl_isa(it, EFL_UI_GRID_ITEM_CLASS))
- {
- ERR("Item must be of type EFL_UI_GRID_ITEM_CLASS");
- return EINA_FALSE;
- }
-
- if (eina_list_data_find(pd->items, it))
- {
- ERR("Item already added to this container!");
- return EINA_FALSE;
- }
-
- if (!efl_ui_widget_sub_object_add(obj, it))
- return EINA_FALSE;
-
- efl_ui_item_container_set(it, obj);
- efl_canvas_group_member_add(pd->pan, it);
- efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
-
- efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_ITEM_SELECTED, _grid_item_selected, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_ITEM_UNSELECTED, _grid_item_unselected, obj);
- efl_event_callback_add(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
-
- return EINA_TRUE;
-}
-
-static void
-_grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *it)
-{
- EFL_UI_GRID_ITEM_CHECK_OR_RETURN(it);
- efl_ui_item_container_set(it, NULL);
-
- pd->items = eina_list_remove(pd->items, it);
- if (efl_ui_item_selected_get(it))
- {
- pd->selected = eina_list_remove(pd->selected, it);
- }
-
- efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_ITEM_SELECTED, _grid_item_selected, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_ITEM_UNSELECTED, _grid_item_unselected, obj);
- efl_event_callback_del(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
-
- efl_canvas_group_member_remove(pd->pan, it);
- _elm_widget_sub_object_redirect_to_top(obj, it);
-}
-
-
-static void
-_grid_clear_internal(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
-{
- Efl_Ui_Grid_Item *it = NULL;
- Eina_List *l, *ll;
- EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
- {
- efl_del(it);
- }
- eina_list_free(pd->selected);
- pd->items = NULL;
- pd->selected = NULL;
-}
-
-/* Pack APIs */
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_pack_clear(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- _grid_clear_internal(obj, pd);
-
- elm_layout_sizing_eval(obj);
- return EINA_TRUE;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_unpack_all(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
-
- Efl_Ui_Grid_Item *it = NULL;
- Eina_List *l, *ll;
- EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
- {
- _grid_item_unpack_internal(obj, pd, it);
- }
- eina_list_free(pd->selected);
- pd->items = NULL;
- pd->selected = NULL;
-
- elm_layout_sizing_eval(obj);
- return EINA_TRUE;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_unpack(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
-{
- Efl_Ui_Grid_Item *item = (Efl_Ui_Grid_Item *)subobj;
-
- if (!eina_list_data_find(pd->items, item))
- {
- ERR("Element is not part of this container");
- return EINA_FALSE;
- }
-
- _grid_item_unpack_internal(obj, pd, item);
-
- elm_layout_sizing_eval(obj);
- return EINA_TRUE;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_pack(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
-{
- return efl_pack_end(obj, subobj);
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
-{
- if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
- EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
- pd->items = eina_list_append(pd->items, subobj);
-
- pid->update_me = EINA_TRUE;
-
- efl_canvas_group_change(obj);
- return EINA_TRUE;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
-{
- if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
- EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
- pd->items = eina_list_prepend(pd->items, subobj);
- // Defered item's placing in group calculation
- pid->update_me = EINA_TRUE;
- _need_update(pd);
- return EINA_TRUE;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_linear_pack_before(Eo *obj,
- Efl_Ui_Grid_Data *pd,
- Efl_Gfx_Entity *subobj,
- const Efl_Gfx_Entity *existing)
-{
- if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
- EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
- EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
-
- pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
- // Defered item's placing in group calculation
- pid->update_begin = EINA_TRUE;
- _need_update(pd);
- return EINA_TRUE;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_linear_pack_after(Eo *obj,
- Efl_Ui_Grid_Data *pd,
- Efl_Gfx_Entity *subobj,
- const Efl_Gfx_Entity *existing)
-{
- if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
- EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
- EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
-
- pd->items = eina_list_append_relative(pd->items, subobj, existing);
- // Defered item's placing in group calculation
- pid->update_begin = EINA_TRUE;
- _need_update(pd);
- return EINA_TRUE;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_grid_efl_pack_linear_pack_at(Eo *obj,
- Efl_Ui_Grid_Data *pd,
- Efl_Gfx_Entity *subobj,
- int index)
-{
- int clamp = clamp_index(pd, index);
- index = index_adjust(pd, index);
- if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
- Efl_Ui_Grid_Item *existing = eina_list_nth(pd->items, index);
- EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
-
- if (clamp == 0)
- pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
- else if (clamp == 1)
- pd->items = eina_list_append(pd->items, subobj);
- else
- pd->items = eina_list_prepend(pd->items, subobj);
-
- // Defered item's placing in group calculation
- pid->update_begin = EINA_TRUE;
- _need_update(pd);
- return EINA_TRUE;
-}
-
-EOLIAN static Efl_Gfx_Entity *
-_efl_ui_grid_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
-{
- index = index_adjust(pd, index);
- return eina_list_nth(pd->items, index);
-}
-
-EOLIAN static Efl_Gfx_Entity *
-_efl_ui_grid_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
-{
- index = index_adjust(pd, index);
- Efl_Gfx_Entity *target = eina_list_nth(pd->items, index);
- _grid_item_unpack_internal(obj, pd, target);
- _need_update(pd);
- return target;
-}
-
-EOLIAN static int
-_efl_ui_grid_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
- Efl_Ui_Grid_Data *pd,
- const Efl_Gfx_Entity *subobj)
-{
- return eina_list_data_idx(pd->items, (void *)subobj);
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- _need_update(pd);
- elm_layout_sizing_eval(obj);
-
- efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- _need_update(pd);
- elm_layout_sizing_eval(obj);
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_gfx_arrangement_content_padding_set(Eo *obj EINA_UNUSED,
- Efl_Ui_Grid_Data *pd,
- double h,
- double v,
- Eina_Bool scalable)
-{
- pd->item.pad.w = (int )h;
- pd->item.pad.h = (int) v;
-
- pd->pad_scalable = !!scalable;
-
- //reset linemax for recalculate layout
- pd->linemax = 0;
- _need_update(pd);
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_gfx_arrangement_content_padding_get(const Eo *obj EINA_UNUSED,
- Efl_Ui_Grid_Data *pd,
- double *h,
- double *v,
- Eina_Bool *scalable)
-{
- //??
- *h = (double) pd->item.pad.w;
- *v = (double) pd->item.pad.h;
- *scalable = !!pd->pad_scalable;
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_gfx_arrangement_content_align_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double h, double v)
-{
- pd->item.align.w = h;
- pd->item.align.h = v;
- _need_update(pd);
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_gfx_arrangement_content_align_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double *h, double *v)
-{
- *h = pd->item.align.w;
- *v = pd->item.align.h;
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED,
- Efl_Ui_Grid_Data *pd,
- Eina_Bool match_content_w,
- Eina_Bool match_content_h)
-{
- pd->match_content_w = !!match_content_w;
- pd->match_content_h = !!match_content_h;
-
- efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h);
-
- elm_layout_sizing_eval(obj);
-}
-
-EOLIAN static void
-_efl_ui_grid_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED,
- Efl_Ui_Grid_Data *pd,
- Efl_Ui_Select_Mode mode)
-{
- Efl_Ui_Grid_Item *selected;
-
- if ((pd->select_mode == EFL_UI_SELECT_MODE_MULTI &&
- mode != EFL_UI_SELECT_MODE_MULTI) ||
- mode == EFL_UI_SELECT_MODE_NONE)
- {
- Eina_List *clone = eina_list_clone(pd->selected);
- EINA_LIST_FREE(clone, selected)
- efl_ui_item_selected_set(selected, EINA_FALSE);
- }
-
- pd->select_mode = mode;
-}
-
-EOLIAN static Efl_Ui_Select_Mode
-_efl_ui_grid_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
-{
- return pd->select_mode;
-}
-
-/* List APIs */
-EOLIAN static void
-_efl_ui_grid_item_scroll(Eo *obj,
- Efl_Ui_Grid_Data *pd,
- Efl_Ui_Grid_Item *item,
- Eina_Bool animation)
-{
- // Need to be implemented here.
- if (pd->pan_resized)
- {
- _item_scroll_internal(obj, item, -1.0, animation);
- }
- else
- {
- pd->scroll.item = item;
- pd->scroll.align = -1.0;
- pd->scroll.anim = animation;
- }
-}
-
-EOLIAN static void
-_efl_ui_grid_item_scroll_align(Eo *obj,
- Efl_Ui_Grid_Data *pd,
- Efl_Ui_Grid_Item *item,
- double align,
- Eina_Bool animation)
-{
- // Need to be implemented here.
- if (pd->pan_resized)
- {
- _item_scroll_internal(obj, item, align, animation);
- }
- else
- {
- pd->scroll.item = item;
- pd->scroll.align = align;
- pd->scroll.anim = animation;
- }
-}
-
-EOLIAN static Efl_Ui_Grid_Item *
-_efl_ui_grid_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
-{
- return pd->last_selected;
-}
-
-EOLIAN static Eina_Iterator *
-_efl_ui_grid_selected_items_get(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- return _grid_item_iterator_new(obj, pd->selected);
-}
-
-EOLIAN static void
-_efl_ui_grid_item_size_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Size2D size)
-{
- pd->item.size = size;
- //reset linemax for recalculate layout.
- pd->linemax = 0;
-
- _need_update(pd);
-}
-
-EOLIAN static Eina_Size2D
-_efl_ui_grid_item_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
-{
- return pd->item.size;
-}
-
-/* Internal EO APIs and hidden overrides */
-#define EFL_UI_GRID_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_grid)
-
#include "efl_ui_grid.eo.c"
diff --git a/src/lib/elementary/efl_ui_grid.eo b/src/lib/elementary/efl_ui_grid.eo
index c1a3e3ab0c..832fcf1c31 100644
--- a/src/lib/elementary/efl_ui_grid.eo
+++ b/src/lib/elementary/efl_ui_grid.eo
@@ -1,100 +1,8 @@
-import efl_ui_grid_item;
-
-class @beta Efl.Ui.Grid extends Efl.Ui.Layout_Base implements
- Efl.Ui.Scrollable_Interactive,
- Efl.Ui.Scrollbar,
- Efl.Pack_Linear, Efl.Pack_Layout,
- Efl.Ui.Layout_Orientable,
- Efl.Ui.Selectable,
- Efl.Ui.Multi_Selectable,
- Efl.Gfx.Arrangement
+class @beta Efl.Ui.Grid extends Efl.Ui.Collection
{
[[Simple grid widget with Pack interface.]]
- methods {
- @property item_size {
- [[Property data of item size.]]
- set {}
- get {}
- values {
- size: Eina.Size2D; [[last selected item of grid.]]
- }
- }
- item_scroll {
- [[scroll move the item to show in the viewport.]]
- params {
- @in item: Efl.Ui.Grid_Item; [[Target item.]]
- @in animation: bool; [[Boolean value for animation of scroll move.]]
- }
- }
- item_scroll_align {
- [[scroll move the item to show at the align position of the viewport.]]
- params {
- @in item: Efl.Ui.Grid_Item; [[Target item.]]
- @in align: double; [[align value in Viewport.]]
- @in animation: bool; [[Boolean value for animation of scroll move.]]
- }
- }
- @property last_selected_item {
- [[Property data of last selected item.]]
- get {}
- values {
- item: Efl.Ui.Grid_Item; [[last selected item of grid.]]
- }
- }
- selected_items_get {
- [[Get the selected items iterator. The iterator sequence will be decided by selection.]]
- return: iterator<Efl.Ui.Grid_Item> @owned @no_unused; [[Iterator covered by selected items list.
- user have to free the iterator after used.]]
- }
- }
+ data: null;
implements {
- //Efl.Object
Efl.Object.constructor;
- Efl.Object.finalize;
- Efl.Object.destructor;
- Efl.Object.invalidate;
-
- //Efl.Canvas
- Efl.Canvas.Group.group_calculate;
- //Efl.Container
- Efl.Container.content_iterate;
- Efl.Container.content_count;
-
- Efl.Ui.Layout_Orientable.orientation { get; set; }
-
- //Efl.Ui.Widget
- Efl.Ui.Widget.theme_apply;
-
- //Efl.Ui.Focus
- //Efl.Ui.Focus.Object.on_focus_update;
-
- //Efl.Pack
- Efl.Pack.pack_clear;
- Efl.Pack.unpack_all;
- Efl.Pack.unpack;
- Efl.Pack.pack;
- Efl.Pack_Linear.pack_end;
-
- Efl.Pack_Linear.pack_begin;
- Efl.Pack_Linear.pack_before;
- Efl.Pack_Linear.pack_after;
- Efl.Pack_Linear.pack_at;
- Efl.Pack_Linear.pack_unpack_at;
- Efl.Pack_Linear.pack_index_get;
- Efl.Pack_Linear.pack_content_get;
- Efl.Pack_Layout.layout_update;
- Efl.Pack_Layout.layout_request;
- Efl.Gfx.Arrangement.content_padding { get; set; }
- Efl.Gfx.Arrangement.content_align { get; set; }
-
- //Efl.Ui.Scrollable
- Efl.Ui.Scrollable_Interactive.match_content { set; }
-
- //Efl.Ui.Multi_Selectable
- Efl.Ui.Multi_Selectable.select_mode {get; set;}
- }
- composite {
- Efl.Ui.Scrollable_Interactive;
- Efl.Ui.Scrollbar;
}
}
diff --git a/src/lib/elementary/efl_ui_grid_default_item.c b/src/lib/elementary/efl_ui_grid_default_item.c
index 65d2c24cf1..4d28cbc7da 100644
--- a/src/lib/elementary/efl_ui_grid_default_item.c
+++ b/src/lib/elementary/efl_ui_grid_default_item.c
@@ -16,50 +16,16 @@
#define MY_CLASS_NAME "Efl.Ui.Grid_Default_Item"
EOLIAN static Efl_Object *
-_efl_ui_grid_default_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
+_efl_ui_grid_default_item_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
{
Eo *eo;
- eo = efl_finalize(efl_super(obj, MY_CLASS));
- ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
- Eina_Error theme_apply = efl_ui_layout_theme_set(obj, "grid_item", NULL, NULL);
- if (theme_apply == EFL_UI_THEME_APPLY_ERROR_GENERIC)
- CRI("Default Item(%p) failed to set theme [efl/grid_item]!", eo);
- return eo;
-}
-
-EOLIAN static void
-_efl_ui_grid_default_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
-{
- efl_destructor(efl_super(obj, MY_CLASS));
-}
-
-/* Efl.Part */
+ eo = efl_constructor(efl_super(obj, MY_CLASS));
-ELM_PART_TEXT_DEFAULT_GET(efl_ui_grid_default_item, "efl.text")
-ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
-ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
-ELM_PART_CONTENT_DEFAULT_GET(efl_ui_grid_default_item, "efl.icon")
-ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
+ if (!elm_widget_theme_klass_get(obj))
+ elm_widget_theme_klass_set(obj, "grid_item");
-EOLIAN static Efl_Object *
-_efl_ui_grid_default_item_efl_part_part_get(const Eo *obj, void *wd EINA_UNUSED, const char *part)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
- if (eina_streq(part, "text"))
- return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_TEXT_CLASS, obj, "efl.text");
- else if (eina_streq(part, "icon"))
- return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_ICON_CLASS, obj, "efl.icon");
- else if (eina_streq(part, "extra"))
- return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_EXTRA_CLASS, obj, "efl.extra");
-
- return efl_part_get(efl_super(obj, MY_CLASS), part);
+ return eo;
}
-/* Efl.Part end */
-
-/* Internal EO APIs and hidden overrides */
-#define EFL_UI_GRID_DEFAULT_ITEM_EXTRA_OPS \
- ELM_PART_TEXT_DEFAULT_OPS(efl_ui_grid_default_item), \
- ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_grid_default_item)
#include "efl_ui_grid_default_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_grid_default_item.eo b/src/lib/elementary/efl_ui_grid_default_item.eo
index 9b3a0eb890..d5c588eae4 100644
--- a/src/lib/elementary/efl_ui_grid_default_item.eo
+++ b/src/lib/elementary/efl_ui_grid_default_item.eo
@@ -1,33 +1,9 @@
-class @beta Efl.Ui.Grid_Default_Item extends Efl.Ui.Grid_Item implements
- Efl.Text,
- Efl.Text_Markup,
- Efl.Ui.L10n,
- Efl.Content
+class @beta Efl.Ui.Grid_Default_Item extends Efl.Ui.Default_Item
{
- [[Grid Default Item class.
- This class need to be sub object of list widget.
- Text and contents can be set using @Efl.Text,
- @Efl.Content or @Efl.Part.]]
+ [[Grid Default Item class.]]
data: null;
- parts {
- text: Efl.Ui.Item_Part_Text; [[The text part for grid default item.
- text part is the caption of grid item.]]
- icon: Efl.Ui.Item_Part_Icon; [[The icon content part for grid default item.
- icon part is the main content of grid item.]]
- end: Efl.Ui.Item_Part_Extra; [[The extra content part for grid default item.
- extra part is the spare content of grid item.
- you can swallow small badge widget such as check, radio.]]
- }
implements {
- //Efl.Object
- Efl.Object.finalize;
- Efl.Object.destructor;
- Efl.Text.text { get; set; }
- Efl.Text_Markup.markup { get; set; }
- Efl.Ui.L10n.l10n_text { get; set; }
- Efl.Content.content { get; set; }
- Efl.Content.content_unset;
- Efl.Part.part_get;
+ Efl.Object.constructor;
}
}
diff --git a/src/lib/elementary/efl_ui_grid_item.c b/src/lib/elementary/efl_ui_grid_item.c
deleted file mode 100644
index 29daea7896..0000000000
--- a/src/lib/elementary/efl_ui_grid_item.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include "elementary_config.h"
-#endif
-
-#define EFL_ACCESS_PROTECTED
-#define EFL_UI_WIDGET_PART_BG_PROTECTED
-
-#include <Elementary.h>
-
-#include "elm_priv.h"
-#include "efl_ui_grid_item_private.h"
-
-#define MY_CLASS EFL_UI_GRID_ITEM_CLASS
-#define MY_CLASS_PFX efl_ui_grid_item
-
-#define MY_CLASS_NAME "Efl.Ui.Grid_Item"
-
-static void
-_sizing_eval(Evas_Object *obj, Efl_Ui_Grid_Item_Data *pd)
-{
- Evas_Coord minh = -1, minw = -1;
- Evas_Coord rest_w = 0, rest_h = 0;
- ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
-
- edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
- rest_w, rest_h);
- evas_object_size_hint_min_set(obj, minw, minh);
-
- pd->needs_size_calc = EINA_FALSE;
-}
-
-static void
-_efl_ui_grid_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Grid_Item_Data *pd)
-{
- if (pd->needs_size_calc) return;
- pd->needs_size_calc = EINA_TRUE;
-
- efl_canvas_group_change(obj);
-}
-
-EOLIAN static void
-_efl_ui_grid_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Grid_Item_Data *pd)
-{
- if (pd->needs_size_calc)
- {
- _sizing_eval(obj, pd);
- pd->needs_size_calc = EINA_FALSE;
- }
-}
-
-EOLIAN static Eo *
-_efl_ui_grid_item_efl_object_constructor(Eo *obj, Efl_Ui_Grid_Item_Data *pd)
-{
- pd->obj = obj;
- obj = efl_constructor(efl_super(obj, MY_CLASS));
-
- return obj;
-}
-
-EOLIAN static Efl_Object *
-_efl_ui_grid_item_efl_object_finalize(Eo *obj, Efl_Ui_Grid_Item_Data *pd EINA_UNUSED)
-{
- Eo *eo;
- eo = efl_finalize(efl_super(obj, MY_CLASS));
- ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
-
- return eo;
-}
-
-EOLIAN static void
-_efl_ui_grid_item_efl_object_destructor(Eo *obj, Efl_Ui_Grid_Item_Data *pd EINA_UNUSED)
-{
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- efl_destructor(efl_super(obj, MY_CLASS));
-}
-
-/* Internal EO APIs and hidden overrides */
-
-#define EFL_UI_GRID_ITEM_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_grid_item)
-
-#include "efl_ui_grid_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_grid_item.eo b/src/lib/elementary/efl_ui_grid_item.eo
deleted file mode 100644
index 99a4abca01..0000000000
--- a/src/lib/elementary/efl_ui_grid_item.eo
+++ /dev/null
@@ -1,12 +0,0 @@
-
-abstract @beta Efl.Ui.Grid_Item extends Efl.Ui.Item
-{
- implements {
- //Efl.Object
- Efl.Object.constructor;
- Efl.Object.finalize;
- Efl.Object.destructor;
- //Efl.Canvas
- Efl.Canvas.Group.group_calculate;
- }
-}
diff --git a/src/lib/elementary/efl_ui_grid_item_private.h b/src/lib/elementary/efl_ui_grid_item_private.h
deleted file mode 100644
index d8c4009826..0000000000
--- a/src/lib/elementary/efl_ui_grid_item_private.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef EFL_UI_GRID_ITEM_PRIVATE_H
-#define EFL_UI_GRID_ITEM_PRIVATE_H
-
-#include "Elementary.h"
-
-typedef struct _Efl_Ui_Grid_Item_Data
-{
- // Eo Objects
- Eo *obj; /* Self-Object */
- Eina_Rect geo;
- int index;
- struct {
- int row;
- int col;
- } pos;
-
- /* Boolean Values */
- Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
- Eina_Bool update_me: 1;
- Eina_Bool update_begin: 1;
-} Efl_Ui_Grid_Item_Data;
-
-
-#define EFL_UI_GRID_ITEM_DATA_GET(o, pd) \
- Efl_Ui_Grid_Item_Data * pd = efl_data_scope_safe_get(o, EFL_UI_GRID_ITEM_CLASS)
-
-#define EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(o, ptr, ...) \
- EFL_UI_GRID_ITEM_DATA_GET(o, ptr); \
- if (EINA_UNLIKELY(!ptr)) \
- { \
- ERR("No widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- return __VA_ARGS__; \
- }
-
-#define EFL_UI_GRID_ITEM_CHECK_OR_RETURN(obj, ...) \
- if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_GRID_ITEM_CLASS))) \
- return __VA_ARGS__;
-
-#endif
diff --git a/src/lib/elementary/efl_ui_grid_private.h b/src/lib/elementary/efl_ui_grid_private.h
deleted file mode 100644
index c9c8e0ef1b..0000000000
--- a/src/lib/elementary/efl_ui_grid_private.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef EFL_UI_GRID_PRIVATE_H
-#define EFL_UI_GRID_PRIVATE_H
-
-#include "Elementary.h"
-
-typedef struct _Efl_Ui_Grid_Data
-{
- // Eo Objects
- Eo *obj;
- Eo *pan; /* Internal pan for scroll */
- Eo *content;
- Eo *smanager; /* Scroll Manager for support scroll with pan */
- Eina_Rect geo;
- Eina_Position2D pre_pos;
- Efl_Ui_Layout_Orientation dir;
-
- struct {
- Efl_Ui_Grid_Item *item; /* Scroll target item */
- double align; /* Item scroll aligned position.
- -1 is for default case of scroll in */
- Eina_Bool anim : 1; /* boolean data for animation on scroll */
- } scroll; /* Item scroll values for deferred operation */
-
- struct {
- Eina_Size2D size;
- Eina_Size2D pad;
- struct {
- double w;
- double h;
- } align;
- int count;
- int row;
- int col;
- } item;
-
- int linemax;
-
- Eina_List *items; /* All item list for internal maintaining */
- Eina_List *selected; /* Selected items list */
- Efl_Ui_Grid_Item *last_selected; /* latest selected item */
-
- Efl_Ui_Select_Mode select_mode; /* Select mode for items
- with single or multiple seleciton */
-
- // Boolean Data
- Eina_Bool freeze_want : 1; /* Flag for Scroll freezing */
- Eina_Bool match_content_w: 1; /* Flag for size matching on content width.
- it will disable horizontal scroll */
- Eina_Bool match_content_h: 1; /* Flag for size matching on content height.
- it will disable vertical scroll */
- Eina_Bool pan_resized : 1; /* Flag for pan resized.
- This value is used for checking scroll is
- calculated after initialized */
- Eina_Bool need_update: 1;
- Eina_Bool pad_scalable: 1;
-} Efl_Ui_Grid_Data;
-
-typedef struct _Item_Iterator
-{
- Eina_Iterator iterator;
- Eina_List *list;
- Eina_Iterator *real_iterator;
- Eo *object;
-} Item_Iterator;
-
-
-#define EFL_UI_GRID_DATA_GET(o, pd) \
- Efl_Ui_Grid_Data * pd = efl_data_scope_safe_get(o, EFL_UI_GRID_CLASS)
-
-#define EFL_UI_GRID_DATA_GET_OR_RETURN(o, ptr, ...) \
- EFL_UI_GRID_DATA_GET(o, ptr); \
- if (EINA_UNLIKELY(!ptr)) \
- { \
- ERR("No widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- return __VA_ARGS__; \
- }
-
-#define EFL_UI_GRID_CHECK(obj) \
- if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_GRID_CLASS))) \
- return
-
-#endif
diff --git a/src/lib/elementary/efl_ui_group_item.c b/src/lib/elementary/efl_ui_group_item.c
new file mode 100644
index 0000000000..9c3c03a9a9
--- /dev/null
+++ b/src/lib/elementary/efl_ui_group_item.c
@@ -0,0 +1,303 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_UI_LIST_DEFAULT_ITEM_PROTECTED
+#define EFL_PART_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "elm_part_helper.h"
+
+#define MY_CLASS EFL_UI_GROUP_ITEM_CLASS
+#define MY_CLASS_PFX efl_ui_group_item
+
+#define MY_CLASS_NAME "Efl.Ui.Grid_Default_Item"
+
+
+typedef struct {
+ Eina_List *registered_items;
+} Efl_Ui_Group_Item_Data;
+
+EOLIAN static Efl_Object*
+_efl_ui_group_item_efl_object_constructor(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED)
+{
+ if (!elm_widget_theme_klass_get(obj))
+ elm_widget_theme_klass_set(obj, "group_item");
+
+ return efl_constructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_group_item_efl_object_invalidate(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED)
+{
+ efl_pack_clear(obj);
+ efl_invalidate(efl_super(obj, MY_CLASS));
+}
+
+static void _unregister_item(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj);
+
+static void
+_invalidate(void *data, const Efl_Event *ev)
+{
+ Efl_Ui_Group_Item_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
+ if (!pd) return;
+ _unregister_item(data, pd, ev->object);
+}
+
+static void
+_register_item(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ efl_ui_item_parent_set(subobj, obj);
+ efl_event_callback_add(subobj, EFL_EVENT_INVALIDATE, _invalidate, obj);
+ pd->registered_items = eina_list_append(pd->registered_items, subobj);
+}
+
+static void
+_unregister_item(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ efl_ui_item_container_set(subobj, NULL);
+ efl_event_callback_del(subobj, EFL_EVENT_INVALIDATE, _invalidate, obj);
+ pd->registered_items = eina_list_remove(pd->registered_items, subobj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_pack_clear(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd)
+{
+ Eo *item;
+
+ while(pd->registered_items)
+ {
+ item = eina_list_data_get(pd->registered_items);
+ efl_del(item);
+ }
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_unpack_all(Eo *obj, Efl_Ui_Group_Item_Data *pd)
+{
+ Eo *item;
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
+
+ EINA_LIST_FREE(pd->registered_items, item)
+ {
+ efl_pack_unpack(container, item);
+ }
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_unpack(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
+
+ if (!efl_pack_unpack(container, subobj))
+ return EINA_FALSE;
+
+ _unregister_item(obj, pd, subobj);
+ return EINA_TRUE;
+}
+
+#define HANDLE_REG_CALL(cond) \
+ if (!(cond)) \
+ { \
+ _unregister_item(obj, pd, subobj); \
+ return EINA_FALSE; \
+ } \
+ return EINA_TRUE;
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_pack(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
+ return efl_pack_end(obj, subobj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
+ int group_index = efl_pack_index_get(container, obj);
+
+ _register_item(obj, pd, subobj);
+ HANDLE_REG_CALL(efl_pack_at(container, subobj, group_index + eina_list_count(pd->registered_items) + 1));
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
+ int group_index = efl_pack_index_get(container, obj);
+
+ _register_item(obj, pd, subobj);
+ HANDLE_REG_CALL(efl_pack_at(container, subobj, group_index + 1));
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
+
+ //FIXME, maybe we should check if existing is really part of this group
+ _register_item(obj, pd, subobj);
+ HANDLE_REG_CALL(efl_pack_before(container, subobj, existing));
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
+
+ //FIXME, maybe we should check if existing is really part of this group
+ _register_item(obj, pd, subobj);
+ HANDLE_REG_CALL(efl_pack_after(container, subobj, existing));
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_group_item_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj, int index)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
+ int group_index = efl_pack_index_get(container, obj);
+
+ int count = eina_list_count(pd->registered_items);
+
+ if (index < -count)
+ return efl_pack_begin(obj, subobj);
+
+ if (index >= count)
+ return efl_pack_end(obj, subobj);
+
+ if (index < 0)
+ index += count;
+
+ _register_item(obj, pd, subobj);
+ HANDLE_REG_CALL(efl_pack_at(container, subobj, group_index + 1 + index));
+}
+
+EOLIAN static Efl_Gfx_Entity*
+_efl_ui_group_item_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Group_Item_Data *pd, int index)
+{
+ Eo *result, *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, NULL);
+ int group_index = efl_pack_index_get(container, obj);
+ int count = eina_list_count(pd->registered_items);
+
+ if (index <= -count)
+ index = 0;
+ else if (index >= count)
+ index = eina_list_count(pd->registered_items);
+ else if (index < 0)
+ index += count;
+
+ result = efl_pack_unpack_at(container, group_index + 1 + index);
+ if (result)
+ _unregister_item(obj, pd, result);
+
+ return result;
+}
+
+EOLIAN static int
+_efl_ui_group_item_efl_pack_linear_pack_index_get(Eo *obj, Efl_Ui_Group_Item_Data *pd, const Efl_Gfx_Entity *subobj)
+{
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, -1);
+ int first_index = efl_pack_index_get(container, obj) + 1;
+ int subobj_index = efl_pack_index_get(container, subobj);
+
+ if (subobj_index == -1) return -1;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(first_index <= subobj_index && subobj_index < (first_index + (int)eina_list_count(pd->registered_items)), -1);
+
+ return subobj_index - (first_index);
+}
+
+EOLIAN static Efl_Gfx_Entity*
+_efl_ui_group_item_efl_pack_linear_pack_content_get(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, int index)
+{
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, NULL);
+ int group_index = efl_pack_index_get(container, obj);
+
+ int count = eina_list_count(pd->registered_items);
+
+ if (index <= -count)
+ return eina_list_data_get(pd->registered_items);
+
+ if (index >= count)
+ return eina_list_last_data_get(pd->registered_items);
+
+ if (index < 0)
+ index += count;
+
+
+ return efl_pack_content_get(container, group_index + 1 + index);
+}
+
+typedef struct {
+ Eina_Iterator iterator;
+ unsigned int current;
+ unsigned int max;
+ Eo *container;
+} Efl_Ui_Group_Item_Iterator;
+
+static Eina_Bool
+_next_item(Efl_Ui_Group_Item_Iterator *it, void **data)
+{
+ if (it->current >= it->max) return EINA_FALSE;
+
+ *data = efl_pack_content_get(it->container, it->current);
+ it->current++;
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Iterator*
+_efl_ui_group_item_efl_container_content_iterate(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED)
+{
+ Eo *container = efl_ui_item_container_get(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(container, NULL);
+ Efl_Ui_Group_Item_Iterator *it;
+
+ it = calloc(1, sizeof (Efl_Ui_Group_Item_Iterator));
+ if (!it) return NULL;
+
+ EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
+
+ it->current = efl_pack_index_get(container, obj) + 1;
+ it->max = it->current + eina_list_count(pd->registered_items);
+ it->container = container;
+
+ it->iterator.version = EINA_ITERATOR_VERSION;
+ it->iterator.next = FUNC_ITERATOR_NEXT(_next_item);
+ it->iterator.get_container = NULL;
+ it->iterator.free = FUNC_ITERATOR_FREE(free);
+
+ return &it->iterator;
+}
+
+EOLIAN static int
+_efl_ui_group_item_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd)
+{
+ return eina_list_count(pd->registered_items);
+}
+
+
+
+
+#include "efl_ui_group_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_group_item.eo b/src/lib/elementary/efl_ui_group_item.eo
new file mode 100644
index 0000000000..ee4cdd8e63
--- /dev/null
+++ b/src/lib/elementary/efl_ui_group_item.eo
@@ -0,0 +1,22 @@
+class @beta Efl.Ui.Group_Item extends Efl.Ui.Default_Item implements Efl.Pack_Linear
+{
+ [[Group item for grids and lists]]
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.invalidate;
+ Efl.Pack.pack_clear;
+ Efl.Pack.unpack_all;
+ Efl.Pack.unpack;
+ Efl.Pack.pack;
+ Efl.Pack_Linear.pack_end;
+ Efl.Pack_Linear.pack_begin;
+ Efl.Pack_Linear.pack_before;
+ Efl.Pack_Linear.pack_after;
+ Efl.Pack_Linear.pack_at;
+ Efl.Pack_Linear.pack_unpack_at;
+ Efl.Pack_Linear.pack_index_get;
+ Efl.Pack_Linear.pack_content_get;
+ Efl.Container.content_iterate;
+ Efl.Container.content_count;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_image.c b/src/lib/elementary/efl_ui_image.c
index dea9ec1b00..916eb2bb6e 100644
--- a/src/lib/elementary/efl_ui_image.c
+++ b/src/lib/elementary/efl_ui_image.c
@@ -7,7 +7,7 @@
#define EFL_ACCESS_COMPONENT_PROTECTED
#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
#define EFL_LAYOUT_CALC_PROTECTED
-#define EFL_UI_CLICKABLE_PROTECTED
+#define EFL_INPUT_CLICKABLE_PROTECTED
#include <Elementary.h>
@@ -584,7 +584,7 @@ _efl_ui_image_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Image_Data *priv)
}
else
{
- efl_ui_clickable_util_bind_to_object(priv->hit_rect, obj);
+ efl_ui_action_connector_bind_clickable_to_object(priv->hit_rect, obj);
}
priv->smooth = EINA_TRUE;
@@ -747,7 +747,7 @@ _key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
if (elm_widget_is_legacy(obj))
evas_object_smart_callback_call(obj, "clicked", NULL);
else
- efl_event_callback_call(obj, EFL_UI_EVENT_CLICKED, NULL);
+ efl_event_callback_call(obj, EFL_INPUT_EVENT_CLICKED, NULL);
return EINA_TRUE;
}
@@ -802,8 +802,8 @@ _efl_ui_image_sizing_eval(Evas_Object *obj)
}
}
- evas_object_size_hint_min_set(obj, minw, minh);
- evas_object_size_hint_max_set(obj, maxw, maxh);
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
+ efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(maxw, maxh));
if (sd->img)
{
@@ -1281,7 +1281,7 @@ _efl_ui_image_efl_layout_calc_calc_thaw(Eo *obj, Efl_Ui_Image_Data *sd)
if (sd->edje)
{
int ret = edje_object_thaw(sd->img);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_calculate(obj);
return ret;
}
return 0;
diff --git a/src/lib/elementary/efl_ui_image.eo b/src/lib/elementary/efl_ui_image.eo
index 728a6c4cb0..f756d179bd 100644
--- a/src/lib/elementary/efl_ui_image.eo
+++ b/src/lib/elementary/efl_ui_image.eo
@@ -16,7 +16,7 @@ struct @beta Efl.Ui.Image_Error
open_error: bool; [[$true if the error happened when opening the file, $false otherwise]]
}
-class @beta Efl.Ui.Image extends Efl.Ui.Widget implements Efl.Ui.Clickable, Efl.Ui.Draggable,
+class @beta Efl.Ui.Image extends Efl.Ui.Widget implements Efl.Input.Clickable, Efl.Ui.Draggable,
Efl.File, Efl.Gfx.Image, Efl.Gfx.Image_Load_Controller, Efl.Player, Efl.Gfx.View,
Efl.Access.Component, Efl.Access.Widget.Action, Efl.Gfx.Color,
Efl.Gfx.Image_Orientable,
diff --git a/src/lib/elementary/efl_ui_image_factory.c b/src/lib/elementary/efl_ui_image_factory.c
index 9bf9f39a9c..4d0c139e8b 100644
--- a/src/lib/elementary/efl_ui_image_factory.c
+++ b/src/lib/elementary/efl_ui_image_factory.c
@@ -2,6 +2,8 @@
# include "elementary_config.h"
#endif
+#define EFL_UI_FACTORY_PROTECTED
+
#include <Elementary.h>
#include "elm_priv.h"
@@ -36,28 +38,29 @@ _efl_ui_image_factory_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Ui_Image_Fa
static Eina_Value
_efl_ui_image_factory_bind(Eo *obj EINA_UNUSED, void *data, const Eina_Value value)
{
- Efl_Gfx_Entity *entity = NULL;
Efl_Ui_Image_Factory_Data *pd = data;
+ Efl_Gfx_Entity *entity;
+ int len, i;
- eina_value_pget(&value, &entity);
-
- efl_ui_property_bind(entity, "filename", pd->property);
+ EINA_VALUE_ARRAY_FOREACH(&value, len, i, entity)
+ efl_ui_property_bind(entity, "filename", pd->property);
return value;
}
EOLIAN static Eina_Future *
-_efl_ui_image_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Image_Factory_Data *pd, Efl_Model *model, Efl_Gfx_Entity *parent)
+_efl_ui_image_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Image_Factory_Data *pd,
+ Eina_Iterator *models, Efl_Gfx_Entity *parent)
{
Eina_Future *f;
if (!parent) return efl_loop_future_rejected(obj, EFL_FACTORY_ERROR_NOT_SUPPORTED);
if (!pd->property) return efl_loop_future_rejected(obj, EFL_FACTORY_ERROR_NOT_SUPPORTED);
- f = efl_ui_factory_create(efl_super(obj, EFL_UI_IMAGE_FACTORY_CLASS), model, parent);
+ f = efl_ui_factory_create(efl_super(obj, EFL_UI_IMAGE_FACTORY_CLASS), models, parent);
return efl_future_then(obj, f,
- .success_type = EINA_VALUE_TYPE_OBJECT,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
.success = _efl_ui_image_factory_bind,
.data = pd);
}
diff --git a/src/lib/elementary/efl_ui_image_zoomable.c b/src/lib/elementary/efl_ui_image_zoomable.c
index 9d834afad2..92b234782a 100644
--- a/src/lib/elementary/efl_ui_image_zoomable.c
+++ b/src/lib/elementary/efl_ui_image_zoomable.c
@@ -6,7 +6,7 @@
#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
#define EFL_UI_SCROLL_MANAGER_PROTECTED
#define EFL_UI_SCROLLBAR_PROTECTED
-#define EFL_UI_CLICKABLE_PROTECTED
+#define EFL_INPUT_CLICKABLE_PROTECTED
#include <Elementary.h>
@@ -111,13 +111,12 @@ _photocam_image_file_set(Evas_Object *obj, Efl_Ui_Image_Zoomable_Data *sd)
static void
_sizing_eval(Evas_Object *obj)
{
- Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1;
+ Evas_Coord minw = 0, minh = 0;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ Eina_Size2D max = efl_gfx_hint_size_combined_max_get(wd->resize_obj);
- evas_object_size_hint_max_get
- (wd->resize_obj, &maxw, &maxh);
- evas_object_size_hint_min_set(obj, minw, minh);
- evas_object_size_hint_max_set(obj, maxw, maxh);
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
+ efl_gfx_hint_size_restricted_max_set(obj, max);
}
static void
@@ -373,19 +372,20 @@ _efl_ui_image_zoomable_pan_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Imag
Eina_List *l;
Evas_Coord ox, oy, ow, oh;
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
ELM_WIDGET_DATA_GET_OR_RETURN(psd->wobj, wd);
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
_image_place(
- wd->obj, psd->wsd->pan_x, psd->wsd->pan_y,
+ psd->wobj, psd->wsd->pan_x, psd->wsd->pan_y,
ox - psd->wsd->g_layer_zoom.imx, oy - psd->wsd->g_layer_zoom.imy, ow,
oh);
EINA_LIST_FOREACH(psd->wsd->grids, l, g)
{
- _grid_load(wd->obj, g);
+ _grid_load(psd->wobj, g);
_grid_place(
- wd->obj, g, psd->wsd->pan_x,
+ psd->wobj, g, psd->wsd->pan_x,
psd->wsd->pan_y, ox - psd->wsd->g_layer_zoom.imx,
oy - psd->wsd->g_layer_zoom.imy, ow, oh);
}
@@ -536,7 +536,7 @@ _tile_preloaded_cb(void *data,
"efl");
efl_event_callback_legacy_call
- (wd->obj, EFL_UI_IMAGE_ZOOMABLE_EVENT_LOADED_DETAIL, NULL);
+ (git->obj, EFL_UI_IMAGE_ZOOMABLE_EVENT_LOADED_DETAIL, NULL);
}
}
}
@@ -1848,7 +1848,7 @@ _efl_ui_image_zoomable_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Image_Zoomable
(priv->img, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, obj);
evas_object_event_callback_add
(priv->img, EVAS_CALLBACK_MOUSE_UP, _mouse_up_cb, obj);
- efl_ui_clickable_util_bind_to_object(priv->img, obj);
+ efl_ui_action_connector_bind_clickable_to_object(priv->img, obj);
evas_object_image_scale_hint_set(priv->img, EVAS_IMAGE_SCALE_HINT_STATIC);
/* XXX: mmm... */
@@ -1860,7 +1860,7 @@ _efl_ui_image_zoomable_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Image_Zoomable
(priv->img, EVAS_CALLBACK_IMAGE_PRELOADED, _main_img_preloaded_cb, obj);
edje_object_size_min_calc(edje, &minw, &minh);
- evas_object_size_hint_min_set(obj, minw, minh);
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
_efl_ui_image_zoomable_edje_object_attach(obj);
@@ -2027,7 +2027,7 @@ _img_proxy_set(Evas_Object *obj, Efl_Ui_Image_Zoomable_Data *sd,
evas_object_image_source_set(sd->img, sd->edje);
evas_object_image_source_visible_set(sd->img, EINA_FALSE);
- evas_object_size_hint_min_set(sd->img, w, h);
+ efl_gfx_hint_size_min_set(sd->img, EINA_SIZE2D(w, h));
evas_object_show(sd->img);
evas_object_show(sd->edje);
diff --git a/src/lib/elementary/efl_ui_internal_text_scroller.c b/src/lib/elementary/efl_ui_internal_text_scroller.c
index 0773b976b5..8ee50a7075 100644
--- a/src/lib/elementary/efl_ui_internal_text_scroller.c
+++ b/src/lib/elementary/efl_ui_internal_text_scroller.c
@@ -63,13 +63,14 @@ _efl_ui_internal_text_scroller_efl_object_constructor(Eo *obj,
}
EOLIAN static void
-_efl_ui_internal_text_scroller_elm_layout_sizing_eval(Eo *obj,
+_efl_ui_internal_text_scroller_efl_canvas_group_group_calculate(Eo *obj,
Efl_Ui_Internal_Text_Scroller_Data *sd)
{
Eina_Size2D size = {-1, -1};
Eina_Rect view = EINA_RECT(0, 0, 0, 0);
Evas_Coord vmw = 0, vmh = 0;
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
EFL_UI_SCROLLER_DATA_GET(obj, psd);
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
@@ -116,10 +117,8 @@ _efl_ui_internal_text_scroller_elm_layout_sizing_eval(Eo *obj,
fsz.w = view.w;
}
- // FIXME: should be restricted_min?
efl_gfx_entity_size_set(sd->text_table, fsz);
- efl_gfx_hint_size_min_set(obj, size);
- efl_gfx_hint_size_max_set(obj, EINA_SIZE2D(-1, size.h));
+ efl_gfx_hint_size_restricted_min_set(obj, size);
}
}
@@ -187,7 +186,4 @@ _efl_ui_internal_text_scroller_viewport_clip_get(const Eo *obj,
/* Internal EO APIs and hidden overrides */
-#define EFL_UI_INTERNAL_TEXT_SCROLLER_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_internal_text_scroller)
-
#include "efl_ui_internal_text_scroller.eo.c"
diff --git a/src/lib/elementary/efl_ui_internal_text_scroller.eo b/src/lib/elementary/efl_ui_internal_text_scroller.eo
index b18c008d76..ea0d573417 100644
--- a/src/lib/elementary/efl_ui_internal_text_scroller.eo
+++ b/src/lib/elementary/efl_ui_internal_text_scroller.eo
@@ -48,5 +48,6 @@ class @beta Efl.Ui.Internal_Text_Scroller extends Efl.Ui.Scroller
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
+ Efl.Canvas.Group.group_calculate;
}
}
diff --git a/src/lib/elementary/efl_ui_item.c b/src/lib/elementary/efl_ui_item.c
index 8b16afd5f2..5061331551 100644
--- a/src/lib/elementary/efl_ui_item.c
+++ b/src/lib/elementary/efl_ui_item.c
@@ -2,159 +2,38 @@
# include "elementary_config.h"
#endif
-#define EFL_ACCESS_PROTECTED
-#define EFL_UI_WIDGET_PART_BG_PROTECTED
-
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_item_private.h"
-//part
-#include "efl_ui_item_part_text.eo.h"
-#include "efl_ui_item_part_icon.eo.h"
-#include "efl_ui_item_part_extra.eo.h"
-#include "efl_ui_item_part_content.eo.h"
-#include "elm_part_helper.h"
#define MY_CLASS EFL_UI_ITEM_CLASS
#define MY_CLASS_PFX efl_ui_item
#define MY_CLASS_NAME "Efl.Ui.Item"
-/* Efl.Part */
-EOLIAN static void
-_efl_ui_item_part_text_efl_text_text_set(Eo *obj, void *pd EINA_UNUSED, const char *text)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- efl_text_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), text);
-
- efl_layout_signal_emit(wd->obj, "efl,state,text,set", "efl");
- elm_layout_sizing_eval(wd->obj);
-}
-
-EOLIAN static const char*
-_efl_ui_item_part_text_efl_text_text_get(const Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_text_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-
-EOLIAN static void
-_efl_ui_item_part_text_efl_text_markup_markup_set(Eo *obj, void *pd EINA_UNUSED, const char *markup)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- efl_text_markup_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), markup);
-
- efl_layout_signal_emit(obj, "efl,state,text,set", "efl");
- elm_layout_sizing_eval(obj);
-}
-
-EOLIAN static const char*
-_efl_ui_item_part_text_efl_text_markup_markup_get(const Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_text_markup_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-
-EOLIAN static const char *
-_efl_ui_item_part_text_efl_ui_l10n_l10n_text_get(const Eo *obj, void *_pd EINA_UNUSED, const char **domain)
-{
- Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return elm_widget_part_translatable_text_get(pd->obj, pd->part, domain);
-}
-
-EOLIAN static void
-_efl_ui_item_part_text_efl_ui_l10n_l10n_text_set(Eo *obj, void *_pd EINA_UNUSED, const char *text, const char *domain)
-{
- Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- elm_widget_part_translatable_text_set(pd->obj, pd->part, text, domain);
-}
-#include "efl_ui_item_part_text.eo.c"
-
-/* Efl.Ui.List_Default_Item_Part_Icon */
-
-Eina_Bool
-_efl_ui_item_part_icon_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
-}
-
-Efl_Gfx_Entity *
-_efl_ui_item_part_icon_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-
-Efl_Gfx_Entity *
-_efl_ui_item_part_icon_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-#include "efl_ui_item_part_icon.eo.c"
-
-Eina_Bool
-_efl_ui_item_part_extra_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
-}
-
-Efl_Gfx_Entity *
-_efl_ui_item_part_extra_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-
-Efl_Gfx_Entity *
-_efl_ui_item_part_extra_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-#include "efl_ui_item_part_extra.eo.c"
-
-Eina_Bool
-_efl_ui_item_part_content_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
-}
-
-Efl_Gfx_Entity *
-_efl_ui_item_part_content_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-
-Efl_Gfx_Entity *
-_efl_ui_item_part_content_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
-{
- Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
- return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
-}
-#include "efl_ui_item_part_content.eo.c"
-/* Efl.Part */
-
static void
_item_select(Eo *obj, Efl_Ui_Item_Data *pd)
{
Efl_Ui_Select_Mode m;
- if (!pd->parent)
- return;
- m = efl_ui_select_mode_get(pd->parent);
- if (m == EFL_UI_SELECT_MODE_NONE || (pd->selected && m != EFL_UI_SELECT_MODE_SINGLE_ALWAYS))
- return;
+
+ if (pd->container)
+ {
+ m = efl_ui_select_mode_get(pd->container);
+ if (m == EFL_UI_SELECT_MODE_NONE || (pd->selected && m != EFL_UI_SELECT_MODE_SINGLE_ALWAYS))
+ return;
+ }
+ else
+ {
+ if (pd->selected)
+ return;
+ }
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- pd->selected = EINA_TRUE;
+ Eina_Bool tmp = pd->selected = EINA_TRUE;
edje_object_signal_emit(wd->resize_obj, "efl,state,selected", "efl");
- efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_SELECTED, NULL);
+ efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED_CHANGED, &tmp);
}
static void
@@ -163,180 +42,54 @@ _item_unselect(Eo *obj, Efl_Ui_Item_Data *pd)
if (!pd->selected) return;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- pd->selected = EINA_FALSE;
+ Eina_Bool tmp = pd->selected =EINA_FALSE;
edje_object_signal_emit(wd->resize_obj, "efl,state,unselected", "efl");
- efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_UNSELECTED, NULL);
+ efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED_CHANGED, &tmp);
}
/* Mouse Controls */
-static Eina_Bool
-_item_longpressed(void *data)
-{
- Efl_Ui_Item *item = data;
- EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd, ECORE_CALLBACK_CANCEL);
-
- pd->longpress_timer = NULL;
-
- efl_event_callback_call(item, EFL_UI_EVENT_LONGPRESSED, NULL);
- return ECORE_CALLBACK_CANCEL;
-}
-
static void
-_item_mouse_down(void *data,
- Evas *evas EINA_UNUSED,
- Evas_Object *obj EINA_UNUSED,
- void *event_info)
+_item_pressed(void *data, const Efl_Event *ev EINA_UNUSED)
{
- Evas_Event_Mouse_Down *ev = event_info;
- Eo *item = data;
- EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
- if (wd->disabled) return;
- if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
-
- edje_object_signal_emit(wd->resize_obj, "efl,state,pressed", "efl");
+ Efl_Ui_Item *obj = data;
+ if (efl_ui_widget_disabled_get(obj)) return;
- pd->longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _item_longpressed, item);
- efl_event_callback_call(item, EFL_UI_EVENT_PRESSED, NULL);
+ efl_layout_signal_emit(obj, "efl,state,pressed", "efl");
}
static void
-_item_mouse_up(void *data,
- Evas *evas EINA_UNUSED,
- Evas_Object *obj EINA_UNUSED,
- void *event_info)
+_item_unpressed(void *data, const Efl_Event *ev EINA_UNUSED)
{
- Evas_Event_Mouse_Up *ev = event_info;
- Eo *item = data;
+ Efl_Ui_Item *obj = data;
Efl_Ui_Select_Mode m;
+ EFL_UI_ITEM_DATA_GET_OR_RETURN(obj, pd);
- if (!efl_ui_item_container_get(item))
- return;
- EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
- if (wd->disabled) return;
- if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
- {
- //FIXME: should we send this message to fallback?
- edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
- //efl_event_callback_call(item, EFL_UI_EVENT_UNPRESSED, NULL);
- return;
- }
+ if (efl_ui_widget_disabled_get(obj)) return;
+ if (!efl_ui_item_container_get(obj)) return;
- if (pd->longpress_timer)
- {
- ecore_timer_del(pd->longpress_timer);
- pd->longpress_timer = NULL;
- }
+ efl_layout_signal_emit(obj, "efl,state,unpressed", "efl");
+ m = efl_ui_select_mode_get(efl_ui_item_container_get(obj));
- edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
- efl_event_callback_call(item, EFL_UI_EVENT_UNPRESSED, NULL);
-
- m = efl_ui_select_mode_get(efl_ui_item_container_get(item));
if ((m != EFL_UI_SELECT_MODE_SINGLE_ALWAYS) && (pd->selected))
- _item_unselect(item, pd);
+ efl_ui_selectable_selected_set(obj, EINA_FALSE);
else if (m != EFL_UI_SELECT_MODE_NONE)
- _item_select(item, pd);
-}
-
-static void
-_item_mouse_move(void *data EINA_UNUSED,
- Evas *evas EINA_UNUSED,
- Evas_Object *obj EINA_UNUSED,
- void *event_info)
-{
- Evas_Event_Mouse_Move *ev = event_info;
- Eo *item = data;
- EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
- if (wd->disabled) return;
- if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
- {
- edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
- return;
- }
-}
-
-static void
-_item_mouse_in(void *data EINA_UNUSED,
- Evas *evas EINA_UNUSED,
- Evas_Object *obj EINA_UNUSED,
- void *event_info)
-{
- Evas_Event_Mouse_In *ev = event_info;
- Eo *item = data;
- EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
- if (wd->disabled) return;
-
- if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+ efl_ui_selectable_selected_set(obj, EINA_TRUE);
}
-static void
-_item_mouse_callback_add(Eo *obj, void *data)
-{
- evas_object_event_callback_add
- (obj, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down, data);
- evas_object_event_callback_add
- (obj, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up, data);
- evas_object_event_callback_add
- (obj, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move, data);
- evas_object_event_callback_add
- (obj, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in, data);
-}
+EFL_CALLBACKS_ARRAY_DEFINE(self_listening,
+ {EFL_INPUT_EVENT_PRESSED, _item_pressed},
+ {EFL_INPUT_EVENT_UNPRESSED, _item_unpressed},
+)
-static void
-_item_mouse_callback_del(Eo *obj, void *data)
-{
- evas_object_event_callback_del_full
- (obj, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down, data);
- evas_object_event_callback_del_full
- (obj, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up, data);
- evas_object_event_callback_del_full
- (obj, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move, data);
- evas_object_event_callback_del_full
- (obj, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in, data);
-}
/* Mouse Controls ends */
-static void
-_sizing_eval(Evas_Object *obj, Efl_Ui_Item_Data *pd)
-{
- Evas_Coord minh = -1, minw = -1;
- Evas_Coord rest_w = 0, rest_h = 0;
- ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
-
- edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
- rest_w, rest_h);
- evas_object_size_hint_min_set(obj, minw, minh);
-
- pd->needs_size_calc = EINA_FALSE;
-}
-
-static void
-_efl_ui_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Item_Data *pd)
-{
- if (pd->needs_size_calc) return;
- pd->needs_size_calc = EINA_TRUE;
-
- efl_canvas_group_change(obj);
-}
-
-EOLIAN static void
-_efl_ui_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Item_Data *pd)
-{
- if (pd->needs_size_calc)
- {
- _sizing_eval(obj, pd);
- pd->needs_size_calc = EINA_FALSE;
- }
-}
-
EOLIAN static Eo *
-_efl_ui_item_efl_object_constructor(Eo *obj, Efl_Ui_Item_Data *pd)
+_efl_ui_item_efl_object_constructor(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
{
- pd->obj = obj;
obj = efl_constructor(efl_super(obj, MY_CLASS));
+ efl_ui_layout_finger_size_multiplier_set(obj, 0, 0);
+
+ efl_event_callback_array_add(obj, self_listening(), obj);
return obj;
}
@@ -351,7 +104,7 @@ _efl_ui_item_efl_object_finalize(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
/* Support Item Focus Feature */
elm_widget_can_focus_set(obj, EINA_TRUE);
- _item_mouse_callback_add(wd->resize_obj, eo);
+ efl_ui_action_connector_bind_clickable_to_object(wd->resize_obj, obj);
return eo;
}
@@ -360,18 +113,17 @@ _efl_ui_item_efl_object_destructor(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- _item_mouse_callback_del(wd->resize_obj, obj);
efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static int
_efl_ui_item_index_get(const Eo *obj, Efl_Ui_Item_Data *pd)
{
- return efl_pack_index_get(pd->parent, obj);
+ return efl_pack_index_get(pd->container, obj);
}
EOLIAN static void
-_efl_ui_item_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool select)
+_efl_ui_item_efl_ui_selectable_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool select)
{
Eina_Bool selected = !!select;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
@@ -382,7 +134,7 @@ _efl_ui_item_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool select)
}
EOLIAN static Eina_Bool
-_efl_ui_item_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
+_efl_ui_item_efl_ui_selectable_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
{
return pd->selected;
}
@@ -390,19 +142,49 @@ _efl_ui_item_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
EOLIAN static void
_efl_ui_item_container_set(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd, Efl_Ui_Widget *container)
{
- pd->parent = container;
+ pd->container = container;
+ if (!pd->container)
+ {
+ pd->parent = NULL;
+ }
}
EOLIAN static Efl_Ui_Widget*
_efl_ui_item_container_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
{
- return pd->parent;
+ return pd->container;
}
+EOLIAN static void
+_efl_ui_item_item_parent_set(Eo *obj, Efl_Ui_Item_Data *pd, Efl_Ui_Item *parent)
+{
+ if (pd->parent)
+ {
+ ERR("Parent is already set on object %p", obj);
+ return;
+ }
+ if (efl_invalidated_get(obj) || efl_invalidating_get(obj))
+ {
+ ERR("Parent cannot be set during invalidate");
+ return;
+ }
+ if (pd->container)
+ {
+ ERR("Parent must be set before adding the object to the container");
+ return;
+ }
+ pd->parent = parent;
+}
-/* Internal EO APIs and hidden overrides */
-#define EFL_UI_ITEM_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_item)
+EOLIAN static Efl_Ui_Item*
+_efl_ui_item_item_parent_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
+{
+ return pd->parent;
+}
+
#include "efl_ui_item.eo.c"
+#include "efl_ui_selectable.eo.c"
+#include "efl_ui_multi_selectable.eo.c"
+#include "efl_ui_single_selectable.eo.c"
diff --git a/src/lib/elementary/efl_ui_item.eo b/src/lib/elementary/efl_ui_item.eo
index 9ece7e4c0c..7dc9060efd 100644
--- a/src/lib/elementary/efl_ui_item.eo
+++ b/src/lib/elementary/efl_ui_item.eo
@@ -1,39 +1,59 @@
-abstract @beta Efl.Ui.Item extends Efl.Ui.Layout_Base implements Efl.Ui.Selectable, Efl.Ui.Clickable
+abstract @beta Efl.Ui.Item extends Efl.Ui.Layout_Base implements Efl.Ui.Selectable, Efl.Input.Clickable
{
- [[Item abstract class for pack widget. All item have to be inherited from this class.]]
+ [[Selectable Item abstraction.
+
+ This class serves as the basis to create widgets acting as selectable items inside containers
+ like @Efl.Ui.List or @Efl.Ui.Grid, for example.
+ @Efl.Ui.Item provides user interaction through the @Efl.Input.Clickable mixin.
+ Items can be pressed, long-pressed, etc, and appropriate events are generated.
+ @Efl.Ui.Item also implements the @Efl.Ui.Selectable interface, meaning that "selected" and
+ "unselected" events are automatically generated.
+
+ Classes inheriting from this one only need to deal with the visual representation of the widget.
+ See for example @Efl.Ui.Grid_Default_Item and @Efl.Ui.List_Default_Item.
+
+ Some events are converted to edje signals so the theme can react to them:
+ @[Efl.Input.Clickable.pressed] -> "efl,state,pressed",
+ @[Efl.Input.Clickable.unpressed] -> "efl,state,unpressed",
+ @[Efl.Ui.Selectable.selected,changed] (true) -> "efl,state,selected",
+ @[Efl.Ui.Selectable.selected,changed] (false) -> "efl,state,unselected".
+ ]]
methods {
@property index {
- [[index number of item from their parent object.]]
- get {}
- values {
- index : int;
- }
- }
- @property selected {
- [[Select property for item object.
- Item can be selected by user mouse/key input also]]
- set {}
+ [[The index of this item inside its container.
+
+ The container must be set through the @Efl.Ui.Item.container property.]]
get {}
values {
- select: bool;
+ index : int; [[The index where to find this item in its $container.]]
}
}
@property container {
[[The container this object is part of.
- You should never use this property yourself, the container will set it. Unsetting this while the item is packed into a container does not have an impact on its state in the container.
+ You should never use this property directly, the container will set it when the
+ item is added.
+ Unsetting this while the item is packed inside a container does not remove the item
+ from the container.
]]
values {
container : Efl.Ui.Widget; [[The container this item is in.]]
}
}
+ @property item_parent {
+ [[The parent of the item.
+
+ This property expresses a tree structure of items. If the parent is NULL the item is added in the root level of the content. The item parent can only be set once, when the object is invalidated, the item parent is set to NULL and still cannot be reset.
+ ]]
+ values {
+ parent : Efl.Ui.Item;
+ }
+ }
}
implements {
- //Efl.Object
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
- //Efl.Canvas
- Efl.Canvas.Group.group_calculate;
+ Efl.Ui.Selectable.selected {get; set;}
}
}
diff --git a/src/lib/elementary/efl_ui_item_part_content.eo b/src/lib/elementary/efl_ui_item_part_content.eo
deleted file mode 100644
index 010f850ee7..0000000000
--- a/src/lib/elementary/efl_ui_item_part_content.eo
+++ /dev/null
@@ -1,9 +0,0 @@
-class @beta Efl.Ui.Item_Part_Content extends Efl.Ui.Layout_Part implements Efl.Content
-{
- [[Item internal content part class]]
- data: null;
- implements {
- Efl.Content.content { get; set; }
- Efl.Content.content_unset;
- }
-}
diff --git a/src/lib/elementary/efl_ui_item_part_extra.eo b/src/lib/elementary/efl_ui_item_part_extra.eo
deleted file mode 100644
index c6433fc08b..0000000000
--- a/src/lib/elementary/efl_ui_item_part_extra.eo
+++ /dev/null
@@ -1,9 +0,0 @@
-class @beta Efl.Ui.Item_Part_Extra extends Efl.Ui.Layout_Part implements Efl.Content
-{
- [[Item internal content of extra part class]]
- data: null;
- implements {
- Efl.Content.content { get; set; }
- Efl.Content.content_unset;
- }
-}
diff --git a/src/lib/elementary/efl_ui_item_part_icon.eo b/src/lib/elementary/efl_ui_item_part_icon.eo
deleted file mode 100644
index 5c9a9e38b0..0000000000
--- a/src/lib/elementary/efl_ui_item_part_icon.eo
+++ /dev/null
@@ -1,9 +0,0 @@
-class @beta Efl.Ui.Item_Part_Icon extends Efl.Ui.Layout_Part implements Efl.Content
-{
- [[Item internal content of icon part class]]
- data: null;
- implements {
- Efl.Content.content { get; set; }
- Efl.Content.content_unset;
- }
-}
diff --git a/src/lib/elementary/efl_ui_item_part_text.eo b/src/lib/elementary/efl_ui_item_part_text.eo
deleted file mode 100644
index 97fdc0e25b..0000000000
--- a/src/lib/elementary/efl_ui_item_part_text.eo
+++ /dev/null
@@ -1,11 +0,0 @@
-class @beta Efl.Ui.Item_Part_Text extends Efl.Ui.Layout_Part implements
- Efl.Text, Efl.Text_Markup, Efl.Ui.L10n
-{
- [[Item internal text part class]]
- data: null;
- implements {
- Efl.Text.text { set; get; }
- Efl.Text_Markup.markup { get; set; }
- Efl.Ui.L10n.l10n_text { get; set; }
- }
-}
diff --git a/src/lib/elementary/efl_ui_item_private.h b/src/lib/elementary/efl_ui_item_private.h
index ea8ac073c9..cd8300b6a2 100644
--- a/src/lib/elementary/efl_ui_item_private.h
+++ b/src/lib/elementary/efl_ui_item_private.h
@@ -6,14 +6,11 @@
typedef struct _Efl_Ui_Item_Data
{
// Eo Objects
- Eo *obj; /* Self-Object */
- Eo *parent; /* Parent Widget */
-
- Ecore_Timer *longpress_timer; /* Timer for longpress handle */
+ Eo *container; /* Parent Widget */
+ Efl_Ui_Item *parent;
// Boolean Data
Eina_Bool selected : 1; /* State for item selected */
- Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
} Efl_Ui_Item_Data;
diff --git a/src/lib/elementary/efl_ui_layout.c b/src/lib/elementary/efl_ui_layout.c
index 1390fc774f..5ae0403331 100644
--- a/src/lib/elementary/efl_ui_layout.c
+++ b/src/lib/elementary/efl_ui_layout.c
@@ -146,7 +146,7 @@ _on_sub_object_size_hint_change(void *data,
{
if (!efl_alive_get(data)) return;
ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
- elm_layout_sizing_eval(data);
+ efl_canvas_group_change(data);
}
static void
@@ -160,24 +160,66 @@ _part_cursor_free(Efl_Ui_Layout_Sub_Object_Cursor *pc)
}
static void
-_sizing_eval(Evas_Object *obj, Efl_Ui_Layout_Data *sd)
+_sizing_eval(Evas_Object *obj, Efl_Ui_Layout_Data *sd, Elm_Layout_Data *ld)
{
- Evas_Coord minh = -1, minw = -1;
- Evas_Coord rest_w = 0, rest_h = 0;
+ int minh = 0, minw = 0;
+ int rest_w = 0, rest_h = 0;
+ Eina_Size2D sz;
ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
if (!efl_alive_get(obj)) return;
- if (sd->restricted_calc_w)
- rest_w = wd->w;
- if (sd->restricted_calc_h)
- rest_h = wd->h;
+ if (sd->calc_subobjs && !evas_smart_objects_calculating_get(evas_object_evas_get(obj)))
+ {
+ Eina_List *l;
+ Eo *subobj;
+ /* user has manually triggered a smart calc and wants subobjs to also calc */
+ EINA_LIST_FOREACH(wd->subobjs, l, subobj)
+ efl_canvas_group_calculate(subobj);
+ }
+ elm_coords_finger_size_adjust(sd->finger_size_multiplier_x, &rest_w,
+ sd->finger_size_multiplier_y, &rest_h);
+ if (ld)
+ sz = efl_gfx_hint_size_combined_min_get(obj);
+ else
+ sz = efl_gfx_hint_size_min_get(obj);
+ minw = sz.w;
+ minh = sz.h;
+
+ rest_w = MAX(minw, rest_w);
+ rest_h = MAX(minh, rest_h);
+
+ if (ld)
+ {
+ Eina_Size2D size = efl_gfx_entity_size_get(sd->obj);
+ if (ld->restricted_calc_w)
+ rest_w = MIN(size.w, rest_w);
+ if (ld->restricted_calc_h)
+ rest_h = MIN(size.h, rest_h);
+ }
edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
rest_w, rest_h);
- evas_object_size_hint_min_set(obj, minw, minh);
+ /* if desired, scale layout by finger size */
+ if (sd->finger_size_multiplier_x)
+ elm_coords_finger_size_adjust(sd->finger_size_multiplier_x, &minw,
+ sd->finger_size_multiplier_y, NULL);
+ if (sd->finger_size_multiplier_y)
+ elm_coords_finger_size_adjust(sd->finger_size_multiplier_x, NULL,
+ sd->finger_size_multiplier_y, &minh);
+
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
+
+ if (ld)
+ ld->restricted_calc_w = ld->restricted_calc_h = EINA_FALSE;
+}
- sd->restricted_calc_w = sd->restricted_calc_h = EINA_FALSE;
+void
+_efl_ui_layout_subobjs_calc_set(Eo *obj, Eina_Bool set)
+{
+ Efl_Ui_Layout_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ EINA_SAFETY_ON_NULL_RETURN(sd);
+ sd->calc_subobjs = !!set;
}
/* common content cases for layout objects: icon and text */
@@ -437,7 +479,7 @@ _visuals_refresh(Evas_Object *obj,
_efl_ui_layout_highlight_in_theme(obj);
_flush_mirrored_state(obj);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -491,6 +533,11 @@ _efl_ui_layout_base_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Layout_Data *sd)
(theme_apply_internal_ret == EFL_UI_THEME_APPLY_ERROR_DEFAULT))
return EFL_UI_THEME_APPLY_ERROR_DEFAULT;
+ /* unset existing size hints to force accurate recalc */
+ efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(0, 0));
+ if (elm_widget_is_legacy(obj))
+ efl_gfx_hint_size_min_set(obj, EINA_SIZE2D(0, 0));
+
return EFL_UI_THEME_APPLY_ERROR_NONE;
}
@@ -577,7 +624,7 @@ _efl_ui_layout_base_efl_ui_widget_widget_sub_object_del(Eo *obj, Efl_Ui_Layout_D
// No need to resize object during destruction
if (wd->resize_obj && efl_alive_get(obj))
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -733,7 +780,8 @@ _on_size_evaluate_signal(void *data,
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
- elm_layout_sizing_eval(data);
+ efl_canvas_group_change(data);
+ efl_canvas_group_calculate(data);
}
EOLIAN static void
@@ -823,16 +871,44 @@ _efl_ui_layout_base_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Layout_Data *sd)
efl_canvas_group_del(efl_super(obj, MY_CLASS));
}
+EOLIAN static void
+_efl_ui_layout_efl_canvas_group_group_calculate(Eo *obj, void *_pd EINA_UNUSED)
+{
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
+ _sizing_eval(obj, efl_data_scope_get(obj, MY_CLASS), NULL);
+}
+
/* rewrite or extend this one on your derived class as to suit your
* needs */
EOLIAN static void
_efl_ui_layout_base_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Layout_Data *sd)
{
- if (sd->needs_size_calc)
- {
- _sizing_eval(obj, sd);
- sd->needs_size_calc = EINA_FALSE;
- }
+ Elm_Layout_Data *ld = efl_data_scope_safe_get(obj, ELM_LAYOUT_MIXIN);
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
+ if ((!ld) || ld->needs_size_calc)
+ _sizing_eval(obj, sd, ld);
+ if (ld) ld->needs_size_calc = EINA_FALSE;
+}
+
+EOLIAN static void
+_efl_ui_layout_base_finger_size_multiplier_get(const Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *sd, unsigned int *mult_x, unsigned int *mult_y)
+{
+ if (mult_x)
+ *mult_x = sd->finger_size_multiplier_x;
+ if (mult_y)
+ *mult_y = sd->finger_size_multiplier_y;
+}
+
+EOLIAN static void
+_efl_ui_layout_base_finger_size_multiplier_set(Eo *obj, Efl_Ui_Layout_Data *sd, unsigned int mult_x, unsigned int mult_y)
+{
+ if ((sd->finger_size_multiplier_x == mult_x) &&
+ (sd->finger_size_multiplier_y == mult_y))
+ return;
+ sd->finger_size_multiplier_x = mult_x;
+ sd->finger_size_multiplier_y = mult_y;
+ if (efl_alive_get(obj))
+ efl_canvas_group_change(obj);
}
static Efl_Ui_Layout_Sub_Object_Cursor *
@@ -1062,7 +1138,7 @@ _efl_ui_layout_content_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Ev
_icon_signal_emit(sd, sub_d, EINA_TRUE);
}
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
end:
return EINA_TRUE;
@@ -1262,7 +1338,7 @@ _efl_ui_layout_text_generic_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *par
edje_object_part_text_escaped_set
(wd->resize_obj, part, NULL);
sd->subs = eina_list_remove_list(sd->subs, l);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
else
@@ -1298,7 +1374,7 @@ _efl_ui_layout_text_generic_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *par
_text_signal_emit(sd, sub_d, EINA_TRUE);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON &&
sd->can_access && !(sub_d->obj))
@@ -1397,7 +1473,7 @@ _efl_ui_layout_box_append(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Eva
sub_d->type = BOX_APPEND;
_layout_box_subobj_init(sd, sub_d, part, child);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -1434,7 +1510,7 @@ _efl_ui_layout_box_prepend(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Ev
sub_d->type = BOX_PREPEND;
_layout_box_subobj_init(sd, sub_d, part, child);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -1476,7 +1552,7 @@ _efl_ui_layout_box_insert_before(Eo *obj, Efl_Ui_Layout_Data *sd, const char *pa
evas_object_event_callback_add
((Evas_Object *)reference, EVAS_CALLBACK_DEL, _box_reference_del, sub_d);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -1514,7 +1590,7 @@ _efl_ui_layout_box_insert_at(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part,
sub_d->p.box.pos = pos;
_layout_box_subobj_init(sd, sub_d, part, child);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -1612,7 +1688,7 @@ _efl_ui_layout_table_pack(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Eva
sd->subs = eina_list_append(sd->subs, sub_d);
efl_parent_set(child, obj);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -1709,31 +1785,38 @@ _efl_ui_layout_base_efl_layout_group_part_exist_get(const Eo *obj, Efl_Ui_Layout
return efl_layout_group_part_exist_get(wd->resize_obj, part);
}
+EOLIAN static void
+_elm_layout_efl_canvas_group_change(Eo *obj, Elm_Layout_Data *ld)
+{
+ Efl_Ui_Layout_Data *sd;
+
+ if (!efl_finalized_get(obj)) return;
+ sd = efl_data_scope_safe_get(obj, EFL_UI_LAYOUT_BASE_CLASS);
+ if (sd->frozen) return;
+ ld->needs_size_calc = EINA_TRUE;
+ efl_canvas_group_change(efl_super(obj, ELM_LAYOUT_MIXIN));
+}
+
/* layout's sizing evaluation is deferred. evaluation requests are
* queued up and only flag the object as 'changed'. when it comes to
* Evas's rendering phase, it will be addressed, finally (see
* _efl_ui_layout_smart_calculate()). */
-static void
-_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Layout_Data *sd)
+EOLIAN static void
+_elm_layout_sizing_eval(Eo *obj, Elm_Layout_Data *ld)
{
- if (!efl_finalized_get(obj)) return;
- if (sd->frozen) return;
- if (sd->needs_size_calc) return;
- sd->needs_size_calc = EINA_TRUE;
-
- evas_object_smart_changed(obj);
+ _elm_layout_efl_canvas_group_change(obj, ld);
}
EAPI void
elm_layout_sizing_restricted_eval(Eo *obj, Eina_Bool w, Eina_Bool h)
{
- Efl_Ui_Layout_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ Elm_Layout_Data *ld = efl_data_scope_safe_get(obj, ELM_LAYOUT_MIXIN);
- if (!sd) return;
- sd->restricted_calc_w = !!w;
- sd->restricted_calc_h = !!h;
+ EINA_SAFETY_ON_NULL_RETURN(ld);
+ ld->restricted_calc_w = !!w;
+ ld->restricted_calc_h = !!h;
- evas_object_smart_changed(obj);
+ efl_canvas_group_change(obj);
}
EOLIAN static int
@@ -1757,7 +1840,7 @@ _efl_ui_layout_base_efl_layout_calc_calc_thaw(Eo *obj, Efl_Ui_Layout_Data *sd)
edje_object_thaw(wd->resize_obj);
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return 0;
}
@@ -2101,15 +2184,17 @@ _content_created(Eo *obj, void *data, const Eina_Value value)
Efl_Ui_Layout_Factory_Request *request = data;
Efl_Gfx_Entity *content = NULL;
Efl_Gfx_Entity *old_content;
+ int len, i;
- eina_value_get(&value, &content);
-
- // Recycle old content
- old_content = efl_content_get(efl_part(obj, request->key));
- if (old_content) efl_ui_factory_release(request->factory, old_content);
+ EINA_VALUE_ARRAY_FOREACH(&value, len, i, content)
+ {
+ // Recycle old content
+ old_content = efl_content_get(efl_part(obj, request->key));
+ if (old_content) efl_ui_factory_release(request->factory, old_content);
- // Set new content
- efl_content_set(efl_part(obj, request->key), content);
+ // Set new content
+ efl_content_set(efl_part(obj, request->key), content);
+ }
return value;
}
@@ -2128,10 +2213,11 @@ _clean_request(Eo *obj EINA_UNUSED, void *data, const Eina_Future *dead_future E
static void
_efl_ui_layout_view_model_content_update(Efl_Ui_Layout_Data *pd, Efl_Ui_Layout_Factory_Tracking *tracking, const char *key)
{
- Efl_Ui_Layout_Factory_Request *request = calloc(1, sizeof (Efl_Ui_Layout_Factory_Request));
+ Efl_Ui_Layout_Factory_Request *request;
Eina_Future *f;
- Efl_Model *model;
+ Efl_Model *models[1];
+ request = calloc(1, sizeof (Efl_Ui_Layout_Factory_Request));
if (!request) return ;
if (tracking->in_flight) eina_future_cancel(tracking->in_flight);
@@ -2141,11 +2227,13 @@ _efl_ui_layout_view_model_content_update(Efl_Ui_Layout_Data *pd, Efl_Ui_Layout_F
request->factory = efl_ref(tracking->factory);
request->tracking = tracking;
- model = efl_ui_view_model_get(pd->obj);
- f = efl_ui_view_factory_create_with_event(tracking->factory, model, pd->obj);
+ models[0] = efl_ui_view_model_get(pd->obj);
+ f = efl_ui_view_factory_create_with_event(tracking->factory,
+ EINA_C_ARRAY_ITERATOR_NEW(models),
+ pd->obj);
f = efl_future_then(pd->obj, f,
.success = _content_created,
- .success_type = EINA_VALUE_TYPE_OBJECT,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
.data = request,
.free = _clean_request);
}
@@ -2433,10 +2521,51 @@ _efl_ui_layout_base_efl_ui_factory_bind_factory_bind(Eo *obj EINA_UNUSED, Efl_Ui
_efl_ui_layout_view_model_content_update(pd, tracking, ss_key);
}
+EOLIAN void
+_efl_ui_layout_base_efl_ui_i18n_language_set(Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char *locale)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ efl_ui_language_set(wd->resize_obj, locale);
+}
+
+EOLIAN const char *
+_efl_ui_layout_base_efl_ui_i18n_language_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+ return efl_ui_language_get(wd->resize_obj);
+}
+
+EOLIAN static void
+_efl_ui_layout_base_efl_ui_l10n_l10n_text_set(Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char *label, const char *domain)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ efl_ui_l10n_text_set(efl_part(obj, efl_ui_widget_default_text_part_get(obj)), label, domain);
+}
+
+EOLIAN static const char *
+_efl_ui_layout_base_efl_ui_l10n_l10n_text_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char **domain)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+ return efl_ui_l10n_text_get(efl_part(obj, efl_ui_widget_default_text_part_get(obj)), domain);
+}
+
+EOLIAN static Eo *
+_efl_ui_layout_efl_object_constructor(Eo *obj, void *_pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, EFL_UI_LAYOUT_CLASS));
+ Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+ /* basic layouts should not obey finger size */
+ sd->finger_size_multiplier_x = sd->finger_size_multiplier_y = 0;
+
+ return obj;
+}
+
EOLIAN static Eo *
_efl_ui_layout_base_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Data *sd)
{
sd->obj = obj;
+ sd->finger_size_multiplier_x = sd->finger_size_multiplier_y = 1;
obj = efl_constructor(efl_super(obj, MY_CLASS));
evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER);
@@ -2451,6 +2580,14 @@ _efl_ui_layout_base_efl_object_finalize(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNU
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
eo = efl_finalize(efl_super(obj, MY_CLASS));
efl_ui_widget_theme_apply(eo);
+ efl_canvas_group_change(obj);
+
+ Elm_Layout_Data *ld = efl_data_scope_safe_get(obj, ELM_LAYOUT_MIXIN);
+ /* need to explicitly set this here to permit group_calc since efl_canvas_group_change
+ * blocks non-finalized objects and the object will not be finalized until after this
+ * function returns
+ */
+ if (ld) ld->needs_size_calc = EINA_TRUE;
win = elm_widget_top_get(obj);
if (efl_isa(win, EFL_UI_WIN_CLASS))
@@ -2702,7 +2839,6 @@ _efl_ui_layout_base_theme_rotation_apply(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UN
/* Internal EO APIs and hidden overrides */
-EAPI EFL_VOID_FUNC_BODY(elm_layout_sizing_eval)
EFL_FUNC_BODY_CONST(elm_layout_text_aliases_get, const Elm_Layout_Part_Alias_Description *, NULL)
EFL_FUNC_BODY_CONST(elm_layout_content_aliases_get, const Elm_Layout_Part_Alias_Description *, NULL)
@@ -2715,9 +2851,9 @@ ELM_LAYOUT_TEXT_ALIASES_IMPLEMENT(MY_CLASS_PFX)
ELM_PART_TEXT_DEFAULT_OPS(efl_ui_layout_base), \
ELM_LAYOUT_CONTENT_ALIASES_OPS(MY_CLASS_PFX), \
ELM_LAYOUT_TEXT_ALIASES_OPS(MY_CLASS_PFX), \
- EFL_OBJECT_OP_FUNC(elm_layout_sizing_eval, _elm_layout_sizing_eval), \
EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _efl_ui_layout_base_efl_object_dbg_info_get)
+
#include "efl_ui_layout_base.eo.c"
#include "efl_ui_layout.eo.c"
diff --git a/src/lib/elementary/efl_ui_layout.eo b/src/lib/elementary/efl_ui_layout.eo
index bdc81db9c2..7e3de17a05 100644
--- a/src/lib/elementary/efl_ui_layout.eo
+++ b/src/lib/elementary/efl_ui_layout.eo
@@ -8,6 +8,9 @@ class Efl.Ui.Layout extends Efl.Ui.Layout_Base implements Efl.File
the group that the data belongs to, in case it's an EET file
(including Edje files).
+ By default, layouts do not apply the finger_size global configuration value
+ when calculating their geometries.
+
@since 1.22
]]
data: null;
@@ -16,5 +19,7 @@ class Efl.Ui.Layout extends Efl.Ui.Layout_Base implements Efl.File
Efl.File.key { get; set; }
Efl.File.mmap { get; set; }
Efl.File.load;
+ Efl.Object.constructor;
+ Efl.Canvas.Group.group_calculate;
}
}
diff --git a/src/lib/elementary/efl_ui_layout_base.eo b/src/lib/elementary/efl_ui_layout_base.eo
index 1266dcef85..4f4624744a 100644
--- a/src/lib/elementary/efl_ui_layout_base.eo
+++ b/src/lib/elementary/efl_ui_layout_base.eo
@@ -12,6 +12,26 @@ abstract Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container,
c_prefix: efl_ui_layout;
data: Efl_Ui_Layout_Data;
methods {
+ @property finger_size_multiplier {
+ [[Set a multiplier for applying finger size to the layout.
+
+ By default, any widget which inherits from this class will apply
+ the finger_size global config value with a 1:1 width:height ratio during sizing
+ calculations. This will cause the widget to scale its size based on the finger_size
+ config value.
+
+ To disable finger_size in a layout's sizing calculations, set the multipliers for both
+ axes to 0.
+
+ @since 1.23
+ ]]
+ set {}
+ get {}
+ values {
+ multiplier_x: uint; [[Multiplier for X axis.]]
+ multiplier_y: uint; [[Multiplier for Y axis.]]
+ }
+ }
@property theme {
[[The theme of this widget, defines which edje group will be used.
@@ -87,6 +107,8 @@ abstract Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container,
Efl.Part.part_get;
Efl.Ui.Property_Bind.property_bind;
Efl.Ui.Factory_Bind.factory_bind;
+ Efl.Ui.L10n.l10n_text { get; set; }
+ Efl.Ui.I18n.language { get; set; }
}
events {
theme,changed: void; [[Called when theme changed]]
diff --git a/src/lib/elementary/efl_ui_layout_factory.c b/src/lib/elementary/efl_ui_layout_factory.c
index 709a31fc85..e13971e666 100644
--- a/src/lib/elementary/efl_ui_layout_factory.c
+++ b/src/lib/elementary/efl_ui_layout_factory.c
@@ -2,6 +2,8 @@
# include "elementary_config.h"
#endif
+#define EFL_UI_FACTORY_PROTECTED
+
#include <Elementary.h>
#include "elm_priv.h"
@@ -73,30 +75,39 @@ _efl_ui_layout_factory_bind(Eo *obj EINA_UNUSED, void *data, const Eina_Value va
{
Efl_Ui_Layout_Factory_Data *pd = data;
Efl_Gfx_Entity *layout;
+ int len, i;
- eina_value_pget(&value, &layout);
+ EINA_VALUE_ARRAY_FOREACH(&value, len, i, layout)
+ {
+ eina_hash_foreach(pd->bind.properties, _property_bind, layout);
+ eina_hash_foreach(pd->bind.factories, _factory_bind, layout);
- efl_ui_layout_theme_set(layout, pd->klass, pd->group, pd->style);
+ evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ }
- eina_hash_foreach(pd->bind.properties, _property_bind, layout);
- eina_hash_foreach(pd->bind.factories, _factory_bind, layout);
+ return value;
+}
- evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0);
- evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
+static void
+_efl_ui_layout_factory_efl_ui_factory_building(const Eo *obj, Efl_Ui_Layout_Factory_Data *pd, Efl_Gfx_Entity *ui_view)
+{
+ if (pd->klass || pd->group || pd->style)
+ efl_ui_layout_theme_set(ui_view, pd->klass, pd->group, pd->style);
- return value;
+ efl_ui_factory_building(efl_super(obj, EFL_UI_LAYOUT_FACTORY_CLASS), ui_view);
}
EOLIAN static Eina_Future *
_efl_ui_layout_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Layout_Factory_Data *pd,
- Efl_Model *model, Efl_Gfx_Entity *parent)
+ Eina_Iterator *models, Efl_Gfx_Entity *parent)
{
Eina_Future *f;
- f = efl_ui_factory_create(efl_super(obj, EFL_UI_LAYOUT_FACTORY_CLASS), model, parent);
+ f = efl_ui_factory_create(efl_super(obj, EFL_UI_LAYOUT_FACTORY_CLASS), models, parent);
return efl_future_then(obj, f,
- .success_type = EINA_VALUE_TYPE_OBJECT,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
.success = _efl_ui_layout_factory_bind,
.data = pd);
}
@@ -139,6 +150,7 @@ _efl_ui_layout_factory_efl_ui_property_bind_property_bind(Eo *obj EINA_UNUSED, E
ss_prop = eina_stringshare_add(property);
ss_old = eina_hash_set(pd->bind.properties, ss_key, ss_prop);
if (ss_old) eina_stringshare_del(ss_old);
+ else ss_key = NULL; // Prevent destruction of key to keep at least one reference
end:
efl_event_callback_call(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, (void*) ss_key);
@@ -147,8 +159,8 @@ _efl_ui_layout_factory_efl_ui_property_bind_property_bind(Eo *obj EINA_UNUSED, E
}
EOLIAN static void
-_efl_ui_layout_factory_theme_config(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd
- , const char *klass, const char *group, const char *style)
+_efl_ui_layout_factory_theme_config(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd,
+ const char *klass, const char *group, const char *style)
{
eina_stringshare_replace(&pd->klass, klass);
eina_stringshare_replace(&pd->group, group);
diff --git a/src/lib/elementary/efl_ui_layout_factory.eo b/src/lib/elementary/efl_ui_layout_factory.eo
index b31486db02..d6d473e655 100644
--- a/src/lib/elementary/efl_ui_layout_factory.eo
+++ b/src/lib/elementary/efl_ui_layout_factory.eo
@@ -16,6 +16,7 @@ class @beta Efl.Ui.Layout_Factory extends Efl.Ui.Caching_Factory
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Ui.Factory.create;
+ Efl.Ui.Factory.building;
Efl.Ui.Property_Bind.property_bind;
Efl.Ui.Factory_Bind.factory_bind;
}
diff --git a/src/lib/elementary/efl_ui_layout_legacy_eo.c b/src/lib/elementary/efl_ui_layout_legacy_eo.c
index 6bec4f9f78..33056b5c03 100644
--- a/src/lib/elementary/efl_ui_layout_legacy_eo.c
+++ b/src/lib/elementary/efl_ui_layout_legacy_eo.c
@@ -1,7 +1,6 @@
Efl_Object *_efl_ui_layout_legacy_efl_object_constructor(Eo *obj, void *pd);
-
static Eina_Bool
_efl_ui_layout_legacy_class_initializer(Efl_Class *klass)
{
@@ -32,4 +31,40 @@ static const Efl_Class_Description _efl_ui_layout_legacy_class_desc = {
NULL
};
-EFL_DEFINE_CLASS(efl_ui_layout_legacy_class_get, &_efl_ui_layout_legacy_class_desc, EFL_UI_LAYOUT_CLASS, EFL_UI_LEGACY_INTERFACE, NULL);
+EFL_DEFINE_CLASS(efl_ui_layout_legacy_class_get, &_efl_ui_layout_legacy_class_desc, EFL_UI_LAYOUT_CLASS, ELM_LAYOUT_MIXIN, EFL_UI_LEGACY_INTERFACE, NULL);
+
+static void _elm_layout_sizing_eval(Eo *obj, Elm_Layout_Data *ld);
+EAPI EFL_VOID_FUNC_BODY(elm_layout_sizing_eval);
+
+static Eina_Bool
+_elm_layout_class_initializer(Efl_Class *klass)
+{
+ const Efl_Object_Ops *opsp = NULL;
+
+ const Efl_Object_Property_Reflection_Ops *ropsp = NULL;
+
+#ifndef ELM_LAYOUT_EXTRA_OPS
+#define ELM_LAYOUT_EXTRA_OPS
+#endif
+
+ EFL_OPS_DEFINE(ops,
+ EFL_OBJECT_OP_FUNC(elm_layout_sizing_eval, _elm_layout_sizing_eval),
+ EFL_OBJECT_OP_FUNC(efl_canvas_group_change, _elm_layout_efl_canvas_group_change),
+ ELM_LAYOUT_EXTRA_OPS
+ );
+ opsp = &ops;
+
+ return efl_class_functions_set(klass, opsp, ropsp);
+}
+
+static const Efl_Class_Description _elm_layout_class_desc = {
+ EO_VERSION,
+ "Elm.Layout",
+ EFL_CLASS_TYPE_MIXIN,
+ sizeof(Elm_Layout_Data),
+ _elm_layout_class_initializer,
+ NULL,
+ NULL
+};
+
+EFL_DEFINE_CLASS(elm_layout_mixin_get, &_elm_layout_class_desc, NULL, NULL);
diff --git a/src/lib/elementary/efl_ui_layout_legacy_eo.h b/src/lib/elementary/efl_ui_layout_legacy_eo.h
index 3ad5c08573..687bd590c5 100644
--- a/src/lib/elementary/efl_ui_layout_legacy_eo.h
+++ b/src/lib/elementary/efl_ui_layout_legacy_eo.h
@@ -19,8 +19,10 @@ typedef Eo Efl_Ui_Layout_Legacy;
* @ingroup Efl_Ui_Layout_Legacy
*/
#define EFL_UI_LAYOUT_LEGACY_CLASS efl_ui_layout_legacy_class_get()
+#define ELM_LAYOUT_MIXIN elm_layout_mixin_get()
EWAPI const Efl_Class *efl_ui_layout_legacy_class_get(void);
+EWAPI const Efl_Class *elm_layout_mixin_get(void);
#endif /* EFL_BETA_API_SUPPORT */
#endif
diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c
index 524c96993d..0281fd8b30 100644
--- a/src/lib/elementary/efl_ui_list.c
+++ b/src/lib/elementary/efl_ui_list.c
@@ -6,1032 +6,23 @@
#define EFL_UI_SCROLL_MANAGER_PROTECTED
#define EFL_UI_SCROLLBAR_PROTECTED
-#include <Elementary.h>
+#include <Efl_Ui.h>
#include "elm_priv.h"
-#include "efl_ui_list_item_private.h"
#include "efl_ui_item_private.h"
-#include "efl_ui_list_private.h"
#define MY_CLASS EFL_UI_LIST_CLASS
#define MY_CLASS_PFX efl_ui_list
#define MY_CLASS_NAME "Efl.Ui.List"
-static void
-_item_scroll_internal(Eo *obj,
- Efl_Ui_List_Item *item,
- double align,
- Eina_Bool anim)
-{
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
- Eina_Rect ipos, view;
- Eina_Position2D vpos;
-
- if (!pd->smanager) return;
-
- ipos = efl_gfx_entity_geometry_get(item);
- view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
- vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
-
- ipos.x = view.x;
- ipos.w = view.w;
-
- // FIXME: align case will not correctly show in the position because of
- // bar size calculation. there are no certain way to know the scroll calcuation finished.
- if (EINA_DBL_EQ(align, -1.0))
- {
- ipos.y = ipos.y + vpos.y - view.y;
- ipos.h = view.h;
- }
- else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
- (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
- {
- ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align);
- ipos.h = view.h;
- }
- else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
-
- efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
-}
-
-static void
-_efl_ui_list_bar_read_and_update(Eo *obj)
-{
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- double vx = 0.0, vy = 0.0;
-
- edje_object_part_drag_value_get
- (wd->resize_obj, "efl.dragable.vbar", NULL, &vy);
-
- /* FIXME: Horizontal Scroll is not yet supported in the list.
- edje_object_part_drag_value_get
- (wd->resize_obj, "efl.dragable.hbar", &vx, NULL);
- */
-
- efl_ui_scrollbar_bar_position_set(pd->smanager, vx, vy);
-}
-
-static void
-_efl_ui_list_reload_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
-{
- Eo *list = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
-
- efl_ui_scrollbar_bar_visibility_update(pd->smanager);
-}
-
-static void
-_efl_ui_list_vbar_drag_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
-{
- _efl_ui_list_bar_read_and_update(data);
-
- Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
- efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
-}
-
-static void
-_efl_ui_list_vbar_press_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
-{
- Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
- efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
-}
-
-static void
-_efl_ui_list_vbar_unpress_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
-{
- Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
- efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
-}
-
-static void
-_efl_ui_list_edje_drag_start_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
-{
- Eo *list = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
-
- _efl_ui_list_bar_read_and_update(list);
-
- pd->freeze_want = efl_ui_scrollable_scroll_freeze_get(pd->smanager);
- efl_ui_scrollable_scroll_freeze_set(pd->smanager, EINA_TRUE);
- efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_START, NULL);
-}
-
-static void
-_efl_ui_list_edje_drag_stop_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
-{
- Eo *list = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
-
- _efl_ui_list_bar_read_and_update(list);
-
- efl_ui_scrollable_scroll_freeze_set(pd->smanager, pd->freeze_want);
- efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL);
-}
-
-static void
-_efl_ui_list_edje_drag_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
-{
- _efl_ui_list_bar_read_and_update(data);
-}
-
-/* FIXME: Horizontal Scroll is not yet supported in the list.
- static void
- _efl_ui_list_hbar_drag_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
- {
- _efl_ui_list_bar_read_and_update(data);
-
- Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
- efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
- }
-
- static void
- _efl_ui_list_hbar_press_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
- {
- Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
- efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
- }
-
- static void
- _efl_ui_list_hbar_unpress_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
- {
- Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
- efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
- }
- */
-
-static void
-_efl_ui_list_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
-{
- Eo *obj = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- double width = 0.0, height = 0.0;
-
- edje_object_calc_force(wd->resize_obj);
- efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height);
- edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
- edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
-}
-
-static void
-_efl_ui_list_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
-{
- Eo *obj = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- double posx = 0.0, posy = 0.0;
-
- efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy);
- edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
- edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
-}
-
-static void
-_efl_ui_list_bar_show_cb(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
-
- if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
- else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
-}
-
-static void
-_efl_ui_list_bar_hide_cb(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
-
- if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
- else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
- edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
-}
-
-static void
-_scroll_edje_object_attach(Eo *obj)
-{
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
-
- efl_layout_signal_callback_add
- (obj, "reload", "efl",
- obj, _efl_ui_list_reload_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag", "efl.dragable.vbar",
- obj, _efl_ui_list_vbar_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,set", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,start", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_start_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,stop", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_stop_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,step", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,page", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "efl,vbar,press", "efl",
- obj, _efl_ui_list_vbar_press_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "efl,vbar,unpress", "efl",
- obj, _efl_ui_list_vbar_unpress_cb, NULL);
-
- /* FIXME: Horizontal Scroll is not yet supported in the list.
- efl_layout_signal_callback_add
- (obj, "drag", "efl.dragable.hbar",
- obj, _efl_ui_list_hbar_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,set", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,start", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_start_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,stop", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_stop_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,step", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "drag,page", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "efl,hbar,press", "efl",
- obj, _efl_ui_list_hbar_press_cb, NULL);
- efl_layout_signal_callback_add
- (obj, "efl,hbar,unpress", "efl",
- obj, _efl_ui_list_hbar_unpress_cb, NULL);
- */
-}
-
-static void
-_scroll_edje_object_detach(Eo *obj)
-{
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
-
- efl_layout_signal_callback_del
- (obj, "reload", "efl",
- obj, _efl_ui_list_reload_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag", "efl.dragable.vbar",
- obj, _efl_ui_list_vbar_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,set", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,start", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_start_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,stop", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_stop_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,step", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,page", "efl.dragable.vbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "efl,vbar,press", "efl",
- obj, _efl_ui_list_vbar_press_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "efl,vbar,unpress", "efl",
- obj, _efl_ui_list_vbar_unpress_cb, NULL);
-
- /* FIXME: Horizontal Scroll is not yet supported in the list.
- efl_layout_signal_callback_del
- (obj, "drag", "efl.dragable.hbar",
- obj, _efl_ui_list_hbar_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,set", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,start", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_start_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,stop", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_stop_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,step", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "drag,page", "efl.dragable.hbar",
- obj, _efl_ui_list_edje_drag_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "efl,hbar,press", "efl",
- obj, _efl_ui_list_hbar_press_cb, NULL);
- efl_layout_signal_callback_del
- (obj, "efl,hbar,unpress", "efl",
- obj, _efl_ui_list_hbar_unpress_cb, NULL);
- */
-}
-
-static void
-_efl_ui_list_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- Eo *obj = data;
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
- if (!pd->smanager) return;
-
- elm_layout_sizing_eval(obj);
-
- if (!pd->pan_resized)
- {
- Eina_Rect view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
- // FIXME: Below code is workaround size check
- if (view.h > 1)
- {
- pd->pan_resized = EINA_TRUE;
- if (pd->scroll.item)
- {
- _item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim);
-
- pd->scroll.item = NULL;
- pd->scroll.align = 0.0;
- pd->scroll.anim = EINA_FALSE;
- return;
- }
- }
- }
-}
-
-static void
-_efl_ui_list_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- elm_layout_sizing_eval(data);
-}
-
-static void
-_efl_ui_list_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- elm_layout_sizing_eval(data);
-}
-
-EOLIAN static Eo *
-_efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED)
+static Eo *
+_efl_ui_list_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
{
- if (!elm_widget_theme_klass_get(obj))
- elm_widget_theme_klass_set(obj, "list");
obj = efl_constructor(efl_super(obj, MY_CLASS));
- return obj;
-}
-
-EOLIAN static Eo *
-_efl_ui_list_efl_object_finalize(Eo *obj,
- Efl_Ui_List_Data *pd)
-{
- obj = efl_finalize(efl_super(obj, MY_CLASS));
-
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
-
- pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
- efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
- efl_composite_attach(obj, pd->smanager);
-
- pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
-
- efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
- edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan);
-
- pd->box = efl_add(EFL_UI_BOX_CLASS, obj,
- efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL));
- efl_ui_mirrored_set(pd->box, efl_ui_mirrored_get(obj));
- efl_content_set(pd->pan, pd->box);
-
- pd->select_mode = EFL_UI_SELECT_MODE_SINGLE;
-
- _scroll_edje_object_attach(obj);
-
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
- _efl_ui_list_bar_size_changed_cb, obj);
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
- _efl_ui_list_bar_pos_changed_cb, obj);
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
- _efl_ui_list_bar_show_cb, obj);
- efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
- _efl_ui_list_bar_hide_cb, obj);
- efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_list_resized_cb, obj);
- efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
- _efl_ui_list_size_hint_changed_cb, obj);
- efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_list_pan_resized_cb, obj);
-
- elm_layout_sizing_eval(obj);
+ efl_ui_collection_position_manager_set(obj, efl_new(EFL_UI_POSITION_MANAGER_LIST_CLASS));
return obj;
}
-EOLIAN static void
-_efl_ui_list_efl_object_invalidate(Eo *obj, Efl_Ui_List_Data *pd)
-{
- _scroll_edje_object_detach(obj);
-
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
- _efl_ui_list_bar_size_changed_cb, obj);
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
- _efl_ui_list_bar_pos_changed_cb, obj);
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
- _efl_ui_list_bar_show_cb, obj);
- efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
- _efl_ui_list_bar_hide_cb, obj);
- efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_list_resized_cb, obj);
- efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
- _efl_ui_list_size_hint_changed_cb, obj);
- efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
- _efl_ui_list_pan_resized_cb, obj);
-
- efl_del(pd->box);
- pd->box = NULL;
-
- efl_del(pd->pan);
- pd->pan = NULL;
-
- efl_del(pd->smanager);
- pd->smanager = NULL;
-
- efl_invalidate(efl_super(obj, MY_CLASS));
-}
-
-EOLIAN static void
-_efl_ui_list_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED)
-{
- // Need to be implemented
- efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
-}
-
-EOLIAN static void
-_efl_ui_list_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Data *pd)
-{
- Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1};
- Eina_Rect view = {};
- Evas_Coord vmw = 0, vmh = 0;
- double xw = 0.0, yw = 0.0;
-
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- if (pd->box)
- {
- min = efl_gfx_hint_size_combined_min_get(pd->box);
- max = efl_gfx_hint_size_max_get(pd->box);
- efl_gfx_hint_weight_get(pd->box, &xw, &yw);
- }
-
- if (pd->smanager)
- view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
-
- if (xw > 0.0)
- {
- if ((min.w > 0) && (view.w < min.w))
- view.w = min.w;
- else if ((max.w > 0) && (view.w > max.w))
- view.w = max.w;
- }
- else if (min.w > 0)
- view.w = min.w;
-
- if (yw > 0.0)
- {
- if ((min.h > 0) && (view.h < min.h))
- view.h = min.h;
- else if ((max.h > 0) && (view.h > max.h))
- view.h = max.h;
- }
- else if (min.h > 0)
- view.h = min.h;
-
- if (pd->box) efl_gfx_entity_size_set(pd->box, EINA_SIZE2D(view.w, view.h));
-
- edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
-
- if (pd->match_content_w) size.w = vmw + min.w;
- if (pd->match_content_h) size.h = vmh + min.h;
-
- max = efl_gfx_hint_size_max_get(obj);
- if ((max.w > 0) && (size.w > max.w)) size.w = max.w;
- if ((max.h > 0) && (size.h > max.h)) size.h = max.h;
-
- efl_gfx_hint_size_min_set(obj, size);
-}
-
-//FIXME: is this box related API could be improved more?
-EOLIAN static int
-_efl_ui_list_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
-{
- return pd->box ? efl_content_count(pd->box) : 0;
-}
-
-EOLIAN static Eina_Iterator *
-_efl_ui_list_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
-{
- return pd->box ? efl_content_iterate(pd->box) : NULL;
-}
-
-/* FIXME: Direction is not supported yet in the list
- EOLIAN static void
- _efl_ui_list_efl_ui_layout_orientable_orientation_set(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_Layout_Orientation dir)
- {
- switch (dir)
- {
- case EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL:
- pd->dir = EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
- break;
- case EFL_UI_LAYOUT_ORIENTATION_VERTICAL:
- case EFL_UI_LAYOUT_ORIENTATION_DEFAULT:
- default:
- pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
- break;
- }
-
- efl_pack_layout_request(obj);
- }
- */
-
-EOLIAN static Eina_Error
-_efl_ui_list_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_List_Data *pd)
-{
- Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
- int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
- if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
-
- efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
-
- elm_layout_sizing_eval(obj);
-
- return int_ret;
-}
-
-static void
-_list_item_pressed(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_List_Item *item = event->object;
- efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item);
-}
-
-static void
-_list_item_unpressed(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_List_Item *item = event->object;
- efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item);
-}
-
-static void
-_list_item_longpressed(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_List_Item *item = event->object;
- efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item);
-}
-
-static void
-_list_item_selected(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_List_Item *item = event->object;
- Efl_Ui_List_Item *selected;
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
-
- /* Single Select */
- if (pd->select_mode != EFL_UI_SELECT_MODE_MULTI)
- {
- EINA_LIST_FREE(pd->selected, selected)
- {
- if (selected != item)
- efl_ui_item_selected_set(selected, EINA_FALSE);
- }
- }
- pd->selected = eina_list_append(pd->selected, item);
- pd->last_selected = item;
-
- efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_SELECTED, item);
-}
-
-static void
-_list_item_unselected(void *data, const Efl_Event *event)
-{
- Eo *obj = data;
- Efl_Ui_List_Item *item = event->object;
- EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
-
- pd->selected = eina_list_remove(pd->selected, item);
- if (pd->last_selected == item) pd->last_selected = NULL;
-
- efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_UNSELECTED, item);
-}
-
-static Eina_Bool
-_list_item_process(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, Efl_Ui_List_Item *it)
-{
- EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
-
- efl_ui_item_container_set(it, obj);
- efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
-
- efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_ITEM_SELECTED, _list_item_selected, obj);
- efl_event_callback_add(it, EFL_UI_EVENT_ITEM_UNSELECTED, _list_item_unselected, obj);
-
- return EINA_TRUE;
-}
-
-static void
-_list_item_clear(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, EINA_UNUSED Efl_Ui_List_Item *it)
-{
- EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it);
- efl_ui_item_container_set(it, NULL);
-
- efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_ITEM_SELECTED, _list_item_selected, obj);
- efl_event_callback_del(it, EFL_UI_EVENT_ITEM_UNSELECTED, _list_item_unselected, obj);
-}
-
-/* Pack APIs */
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_pack_clear(Eo *obj, Efl_Ui_List_Data *pd)
-{
- Eina_Bool ret = efl_pack_clear(pd->box);
-
- if (ret)
- {
- eina_list_free(pd->items);
- eina_list_free(pd->selected);
- pd->items = NULL;
- pd->selected = NULL;
- }
-
- elm_layout_sizing_eval(obj);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_unpack_all(Eo *obj, Efl_Ui_List_Data *pd)
-{
- Eina_Bool ret = efl_pack_unpack_all(pd->box);
-
- if (ret)
- {
- Efl_Ui_List_Item *it = NULL;
- EINA_LIST_FREE(pd->items, it)
- {
- _list_item_clear(obj, pd, it);
- }
- eina_list_free(pd->selected);
- pd->items = NULL;
- pd->selected = NULL;
- }
-
- elm_layout_sizing_eval(obj);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_unpack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
-{
- Eina_Bool ret = efl_pack_unpack(pd->box, subobj);
- Efl_Ui_List_Item *item = (Efl_Ui_List_Item *)subobj;
-
- if (ret)
- {
- pd->items = eina_list_remove(pd->items, item);
- if (efl_ui_item_selected_get(item))
- {
- pd->selected = eina_list_remove(pd->selected, item);
- }
- _list_item_clear(obj, pd, item);
- }
-
- elm_layout_sizing_eval(obj);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_pack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
-{
- if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
-
- Eina_Bool ret = efl_pack_end(pd->box, subobj);
- pd->items = eina_list_append(pd->items, subobj);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
-{
- if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
-
- Eina_Bool ret = efl_pack_end(pd->box, subobj);
- pd->items = eina_list_append(pd->items, subobj);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
-{
- if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
-
- Eina_Bool ret = efl_pack_begin(pd->box, subobj);
- pd->items = eina_list_prepend(pd->items, subobj);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_linear_pack_before(Eo *obj,
- Efl_Ui_List_Data *pd,
- Efl_Gfx_Entity *subobj,
- const Efl_Gfx_Entity *existing)
-{
- if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
- EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
-
- Eina_Bool ret = efl_pack_before(pd->box, subobj, existing);
- pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_linear_pack_after(Eo *obj,
- Efl_Ui_List_Data *pd,
- Efl_Gfx_Entity *subobj,
- const Efl_Gfx_Entity *existing)
-{
- if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
- EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
-
- Eina_Bool ret = efl_pack_after(pd->box, subobj, existing);
- pd->items = eina_list_append_relative(pd->items, subobj, existing);
- return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_ui_list_efl_pack_linear_pack_at(Eo *obj,
- Efl_Ui_List_Data *pd,
- Efl_Gfx_Entity *subobj,
- int index)
-{
- if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
- Efl_Ui_List_Item *existing = efl_pack_content_get(pd->box, index);
-
- Eina_Bool ret = efl_pack_at(pd->box, subobj, index);
- pd->items = eina_list_append_relative(pd->items, subobj, existing);
- return ret;
-}
-
-EOLIAN static Efl_Gfx_Entity *
-_efl_ui_list_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index)
-{
- return efl_pack_content_get(pd->box, index);
-}
-
-EOLIAN static Efl_Gfx_Entity *
-_efl_ui_list_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index)
-{
- return efl_pack_unpack_at(pd->box, index);
-}
-
-EOLIAN static int
-_efl_ui_list_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
- Efl_Ui_List_Data *pd,
- const Efl_Gfx_Entity *subobj)
-{
- return efl_pack_index_get(pd->box, subobj);
-}
-
-EOLIAN static void
-_efl_ui_list_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_List_Data *pd)
-{
- efl_pack_layout_update(pd->box);
- elm_layout_sizing_eval(obj);
-
- efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
-}
-
-EOLIAN static void
-_efl_ui_list_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_List_Data *pd)
-{
- efl_pack_layout_request(pd->box);
- elm_layout_sizing_eval(obj);
-}
-
-EOLIAN static void
-_efl_ui_list_efl_gfx_arrangement_content_padding_set(Eo *obj EINA_UNUSED,
- Efl_Ui_List_Data *pd,
- double h,
- double v,
- Eina_Bool scalable)
-{
- efl_gfx_arrangement_content_padding_set(pd->box, h, v, scalable);
-}
-
-EOLIAN static void
-_efl_ui_list_efl_gfx_arrangement_content_padding_get(const Eo *obj EINA_UNUSED,
- Efl_Ui_List_Data *pd,
- double *h,
- double *v,
- Eina_Bool *scalable)
-{
- efl_gfx_arrangement_content_padding_get(pd->box, h, v, scalable);
-}
-
-/* FIXME: align could not work properly on the list
- EOLIAN static void
- _efl_ui_list_efl_gfx_arrangement_content_align_set(Eo *obj, Efl_Ui_List_Data *pd, double h, double v)
- {
- efl_gfx_arrangement_content_align_set(pd->box, h, v);
- }
-
- EOLIAN static void
- _efl_ui_list_efl_gfx_arrangement_content_align_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, double *h, double *v)
- {
- efl_gfx_arrangement_content_align_get(pd->box, &h, &v);
- }
- */
-
-/* Scroll APIs */
-EOLIAN static void
-_efl_ui_list_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED,
- Efl_Ui_List_Data *pd,
- Eina_Bool match_content_w,
- Eina_Bool match_content_h)
-{
- pd->match_content_w = !!match_content_w;
- pd->match_content_h = !!match_content_h;
-
- efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h);
-
- elm_layout_sizing_eval(obj);
-}
-
-EOLIAN static void
-_efl_ui_list_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED,
- Efl_Ui_List_Data *pd,
- Efl_Ui_Select_Mode mode)
-{
- Efl_Ui_List_Item *selected;
-
- if ((pd->select_mode == EFL_UI_SELECT_MODE_MULTI &&
- mode != EFL_UI_SELECT_MODE_MULTI) ||
- mode == EFL_UI_SELECT_MODE_NONE)
- {
- Eina_List *clone = eina_list_clone(pd->selected);
- EINA_LIST_FREE(clone, selected)
- efl_ui_item_selected_set(selected, EINA_FALSE);
- }
-
- pd->select_mode = mode;
-}
-
-EOLIAN static Efl_Ui_Select_Mode
-_efl_ui_list_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
-{
- return pd->select_mode;
-}
-
-/* List APIs */
-EOLIAN static void
-_efl_ui_list_item_scroll(Eo *obj,
- Efl_Ui_List_Data *pd,
- Efl_Ui_List_Item *item,
- Eina_Bool animation)
-{
- // Need to be implemented here.
- if (pd->pan_resized)
- {
- _item_scroll_internal(obj, item, -1.0, animation);
- }
- else
- {
- pd->scroll.item = item;
- pd->scroll.align = -1.0;
- pd->scroll.anim = animation;
- }
-}
-
-EOLIAN static void
-_efl_ui_list_item_scroll_align(Eo *obj,
- Efl_Ui_List_Data *pd,
- Efl_Ui_List_Item *item,
- double align,
- Eina_Bool animation)
-{
- // Need to be implemented here.
- if (pd->pan_resized)
- {
- _item_scroll_internal(obj, item, align, animation);
- }
- else
- {
- pd->scroll.item = item;
- pd->scroll.align = align;
- pd->scroll.anim = animation;
- }
-}
-
-EOLIAN static Efl_Ui_List_Item *
-_efl_ui_list_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
-{
- return pd->last_selected;
-}
-
-static Eina_Bool
-_list_item_iterator_next(Item_Iterator *it, void **data)
-{
- Efl_Ui_List_Item *item;
-
- if (!eina_iterator_next(it->real_iterator, (void **)&item))
- return EINA_FALSE;
-
- if (data) *data = item;
- return EINA_TRUE;
-}
-
-static Eo *
-_list_item_iterator_get_container(Item_Iterator *it)
-{
- return it->object;
-}
-
-static void
-_list_item_iterator_free(Item_Iterator *it)
-{
- eina_iterator_free(it->real_iterator);
- eina_list_free(it->list);
- free(it);
-}
-
-EOLIAN static Eina_Iterator *
-_efl_ui_list_selected_items_get(Eo *obj, Efl_Ui_List_Data *pd)
-{
- Item_Iterator *item;
-
- item = calloc(1, sizeof(*item));
- if (!item) return NULL;
-
- EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR);
-
- item->list = eina_list_clone(pd->selected);
- item->real_iterator = eina_list_iterator_new(item->list);
- item->iterator.version = EINA_ITERATOR_VERSION;
- item->iterator.next = FUNC_ITERATOR_NEXT(_list_item_iterator_next);
- item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_list_item_iterator_get_container);
- item->iterator.free = FUNC_ITERATOR_FREE(_list_item_iterator_free);
- item->object = obj;
-
- return &item->iterator;
-}
-
-/* Internal EO APIs and hidden overrides */
-#define EFL_UI_LIST_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_list)
-
#include "efl_ui_list.eo.c"
diff --git a/src/lib/elementary/efl_ui_list.eo b/src/lib/elementary/efl_ui_list.eo
index 72098a14d8..3cb2fea202 100644
--- a/src/lib/elementary/efl_ui_list.eo
+++ b/src/lib/elementary/efl_ui_list.eo
@@ -1,89 +1,8 @@
-import efl_ui_list_item;
-
-class @beta Efl.Ui.List extends Efl.Ui.Layout_Base implements
- Efl.Ui.Scrollable_Interactive,
- Efl.Ui.Scrollbar,
- Efl.Pack_Linear, Efl.Pack_Layout,
- Efl.Ui.Selectable,
- Efl.Ui.Multi_Selectable,
- Efl.Gfx.Arrangement
+class @beta Efl.Ui.List extends Efl.Ui.Collection
{
[[Simple list widget with Pack interface.]]
- methods {
- item_scroll {
- [[scroll move the item to show in the viewport.]]
- params {
- @in item: Efl.Ui.List_Item; [[Target item.]]
- @in animation: bool; [[Boolean value for animation of scroll move.]]
- }
- }
- item_scroll_align {
- [[scroll move the item to show at the align position of the viewport.]]
- params {
- @in item: Efl.Ui.List_Item; [[Target item.]]
- @in align: double; [[align value in Viewport.]]
- @in animation: bool; [[Boolean value for animation of scroll move.]]
- }
- }
- @property last_selected_item {
- [[Property data of last selected item.]]
- get {}
- values {
- return: Efl.Ui.List_Item; [[last selected item of list.]]
- }
- }
- selected_items_get {
- [[Get the selected items iterator. The iterator sequence will be decided by selection.]]
- return: iterator<Efl.Ui.List_Item> @owned @no_unused; [[Iterator covered by selected items list.
- user have to free the iterator after used.]]
- }
- }
+ data: null;
implements {
- //Efl.Object
Efl.Object.constructor;
- Efl.Object.finalize;
- Efl.Object.invalidate;
-
- //Efl.Canvas
- Efl.Canvas.Group.group_calculate;
-
- //Efl.Container
- Efl.Container.content_iterate;
- Efl.Container.content_count;
-
- //Efl.Ui.Layout_Orientable.orientation { get; set; } //TODO
-
- //Efl.Ui.Widget
- Efl.Ui.Widget.theme_apply;
-
- //Efl.Ui.Focus
- //Efl.Ui.Focus.Object.on_focus_update;
-
- //Efl.Pack
- Efl.Pack.pack_clear;
- Efl.Pack.unpack_all;
- Efl.Pack.unpack;
- Efl.Pack.pack;
- Efl.Pack_Linear.pack_begin;
- Efl.Pack_Linear.pack_end;
- Efl.Pack_Linear.pack_before;
- Efl.Pack_Linear.pack_after;
- Efl.Pack_Linear.pack_at;
- Efl.Pack_Linear.pack_content_get;
- Efl.Pack_Linear.pack_unpack_at;
- Efl.Pack_Linear.pack_index_get;
- Efl.Pack_Layout.layout_update;
- Efl.Pack_Layout.layout_request;
- Efl.Gfx.Arrangement.content_padding { get; set; }
-
- //Efl.Ui.Scrollable
- Efl.Ui.Scrollable_Interactive.match_content { set; }
-
- //Efl.Ui.Multi_Selectable
- Efl.Ui.Multi_Selectable.select_mode {get; set;}
- }
- composite {
- Efl.Ui.Scrollable_Interactive;
- Efl.Ui.Scrollbar;
}
}
diff --git a/src/lib/elementary/efl_ui_list_default_item.c b/src/lib/elementary/efl_ui_list_default_item.c
index d95f988ee7..ff2ce75d87 100644
--- a/src/lib/elementary/efl_ui_list_default_item.c
+++ b/src/lib/elementary/efl_ui_list_default_item.c
@@ -16,47 +16,15 @@
#define MY_CLASS_NAME "Efl.Ui.List_Default_Item"
EOLIAN static Efl_Object *
-_efl_ui_list_default_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
+_efl_ui_list_default_item_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
{
Eo *eo;
- eo = efl_finalize(efl_super(obj, MY_CLASS));
- ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
- Eina_Error theme_apply_ret = efl_ui_layout_theme_set(obj, "list_item", NULL, NULL);
- if (theme_apply_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC)
- CRI("Default Item(%p) failed to set theme [efl/list_item]!", eo);
- return eo;
-}
-
-EOLIAN static void
-_efl_ui_list_default_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
-{
- efl_destructor(efl_super(obj, MY_CLASS));
-}
+ eo = efl_constructor(efl_super(obj, MY_CLASS));
-ELM_PART_TEXT_DEFAULT_GET(efl_ui_list_default_item, "efl.text")
-ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
-ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
-ELM_PART_CONTENT_DEFAULT_GET(efl_ui_list_default_item, "efl.icon")
-ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
+ if (!elm_widget_theme_klass_get(obj))
+ elm_widget_theme_klass_set(obj, "list_item");
-EOLIAN static Efl_Object *
-_efl_ui_list_default_item_efl_part_part_get(const Eo *obj, void *wd EINA_UNUSED, const char *part)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
- if (eina_streq(part, "text"))
- return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_TEXT_CLASS, obj, "efl.text");
- else if (eina_streq(part, "icon"))
- return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_ICON_CLASS, obj, "efl.icon");
- else if (eina_streq(part, "extra"))
- return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_EXTRA_CLASS, obj, "efl.extra");
-
- return efl_part_get(efl_super(obj, MY_CLASS), part);
+ return eo;
}
-
-/* Internal EO APIs and hidden overrides */
-#define EFL_UI_LIST_DEFAULT_ITEM_EXTRA_OPS \
- ELM_PART_TEXT_DEFAULT_OPS(efl_ui_list_default_item), \
- ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_list_default_item)
-
#include "efl_ui_list_default_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_list_default_item.eo b/src/lib/elementary/efl_ui_list_default_item.eo
index ee4e770f5d..3b0c768920 100644
--- a/src/lib/elementary/efl_ui_list_default_item.eo
+++ b/src/lib/elementary/efl_ui_list_default_item.eo
@@ -1,30 +1,9 @@
-class @beta Efl.Ui.List_Default_Item extends Efl.Ui.List_Item implements
- Efl.Text,
- Efl.Text_Markup,
- Efl.Content
+class @beta Efl.Ui.List_Default_Item extends Efl.Ui.Default_Item
{
- [[List Default Item class.
- This class need to be sub object of list widget.
- text and contents can be appliable by efl_text,
- efl_content or efl_part APIs.]]
+ [[List Default Item class.]]
data: null;
- parts {
- text: Efl.Ui.Item_Part_Text; [[The text part for list default item.]]
- icon: Efl.Ui.Item_Part_Icon; [[The icon content part for list default item.
- icon part is the left-side content of list item.]]
- extra: Efl.Ui.Item_Part_Extra; [[The extra content part for list default item.
- extra part is the right-side content of list item.]]
- }
implements {
- //Efl.Object
- Efl.Object.finalize;
- Efl.Object.destructor;
- Efl.Text.text { get; set; }
- Efl.Text_Markup.markup { get; set; }
- Efl.Ui.L10n.l10n_text { get; set; }
- Efl.Content.content { get; set; }
- Efl.Content.content_unset;
- Efl.Part.part_get;
+ Efl.Object.constructor;
}
}
diff --git a/src/lib/elementary/efl_ui_list_item.c b/src/lib/elementary/efl_ui_list_item.c
deleted file mode 100644
index 1fe67e9c0c..0000000000
--- a/src/lib/elementary/efl_ui_list_item.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include "elementary_config.h"
-#endif
-
-#define EFL_ACCESS_PROTECTED
-#define EFL_UI_WIDGET_PART_BG_PROTECTED
-
-#include <Elementary.h>
-
-#include "elm_priv.h"
-#include "efl_ui_list_item_private.h"
-
-#define MY_CLASS EFL_UI_LIST_ITEM_CLASS
-#define MY_CLASS_PFX efl_ui_list_item
-
-#define MY_CLASS_NAME "Efl.Ui.List_Item"
-
-static void
-_sizing_eval(Evas_Object *obj, Efl_Ui_List_Item_Data *pd)
-{
- Evas_Coord minh = -1, minw = -1;
- Evas_Coord rest_w = 0, rest_h = 0;
- ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
-
- edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
- rest_w, rest_h);
- evas_object_size_hint_min_set(obj, minw, minh);
-
- pd->needs_size_calc = EINA_FALSE;
-}
-
-static void
-_efl_ui_list_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Item_Data *pd)
-{
- if (pd->needs_size_calc) return;
- pd->needs_size_calc = EINA_TRUE;
-
- efl_canvas_group_change(obj);
-}
-
-EOLIAN static void
-_efl_ui_list_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_List_Item_Data *pd)
-{
- if (pd->needs_size_calc)
- {
- _sizing_eval(obj, pd);
- pd->needs_size_calc = EINA_FALSE;
- }
-}
-
-EOLIAN static Eo *
-_efl_ui_list_item_efl_object_constructor(Eo *obj, Efl_Ui_List_Item_Data *pd)
-{
- pd->obj = obj;
- obj = efl_constructor(efl_super(obj, MY_CLASS));
-
- return obj;
-}
-
-EOLIAN static Efl_Object *
-_efl_ui_list_item_efl_object_finalize(Eo *obj, Efl_Ui_List_Item_Data *pd EINA_UNUSED)
-{
- Eo *eo;
- eo = efl_finalize(efl_super(obj, MY_CLASS));
- ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
-
- return eo;
-}
-
-EOLIAN static void
-_efl_ui_list_item_efl_object_destructor(Eo *obj, Efl_Ui_List_Item_Data *pd EINA_UNUSED)
-{
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- efl_destructor(efl_super(obj, MY_CLASS));
-}
-
-/* Internal EO APIs and hidden overrides */
-
-#define EFL_UI_LIST_ITEM_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_list_item)
-
-#include "efl_ui_list_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_list_item.eo b/src/lib/elementary/efl_ui_list_item.eo
deleted file mode 100644
index 2997926cfd..0000000000
--- a/src/lib/elementary/efl_ui_list_item.eo
+++ /dev/null
@@ -1,12 +0,0 @@
-
-abstract @beta Efl.Ui.List_Item extends Efl.Ui.Item
-{
- implements {
- //Efl.Object
- Efl.Object.constructor;
- Efl.Object.finalize;
- Efl.Object.destructor;
- //Efl.Canvas
- Efl.Canvas.Group.group_calculate;
- }
-}
diff --git a/src/lib/elementary/efl_ui_list_item_private.h b/src/lib/elementary/efl_ui_list_item_private.h
deleted file mode 100644
index 0df36bc459..0000000000
--- a/src/lib/elementary/efl_ui_list_item_private.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef EFL_UI_LIST_ITEM_PRIVATE_H
-#define EFL_UI_LIST_ITEM_PRIVATE_H
-
-#include "Elementary.h"
-
-typedef struct _Efl_Ui_List_Item_Data
-{
- // Eo Objects
- Eo *obj; /* Self-Object */
- Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
-} Efl_Ui_List_Item_Data;
-
-
-#define EFL_UI_LIST_ITEM_DATA_GET(o, pd) \
- Efl_Ui_List_Item_Data * pd = efl_data_scope_safe_get(o, EFL_UI_LIST_ITEM_CLASS)
-
-#define EFL_UI_LIST_ITEM_DATA_GET_OR_RETURN(o, ptr, ...) \
- EFL_UI_LIST_ITEM_DATA_GET(o, ptr); \
- if (EINA_UNLIKELY(!ptr)) \
- { \
- ERR("No widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- return __VA_ARGS__; \
- }
-
-#define EFL_UI_LIST_ITEM_CHECK_OR_RETURN(obj, ...) \
- if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_LIST_ITEM_CLASS))) \
- return __VA_ARGS__;
-
-#endif
diff --git a/src/lib/elementary/efl_ui_list_placeholder_item.c b/src/lib/elementary/efl_ui_list_placeholder_item.c
index 1e4d291fe5..9173646375 100644
--- a/src/lib/elementary/efl_ui_list_placeholder_item.c
+++ b/src/lib/elementary/efl_ui_list_placeholder_item.c
@@ -44,7 +44,7 @@ _efl_ui_list_placeholder_item_efl_part_part_get(const Eo *obj, void *wd EINA_UNU
{
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
if (eina_streq(part, "content"))
- return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_CONTENT_CLASS, obj, "efl.content");
+ return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.content");
return efl_part_get(efl_super(obj, MY_CLASS), part);
}
diff --git a/src/lib/elementary/efl_ui_list_placeholder_item.eo b/src/lib/elementary/efl_ui_list_placeholder_item.eo
index e9dbcab477..fc78f4da84 100644
--- a/src/lib/elementary/efl_ui_list_placeholder_item.eo
+++ b/src/lib/elementary/efl_ui_list_placeholder_item.eo
@@ -1,12 +1,12 @@
-class @beta Efl.Ui.List_Placeholder_Item extends Efl.Ui.List_Item implements Efl.Content
+class @beta Efl.Ui.List_Placeholder_Item extends Efl.Ui.Item implements Efl.Content
{
[[List Placeholder Item class. This item have only one swallow space,
thus user can decorate item by filling the swallow with
any kind of container.]]
data: null;
parts {
- content: Efl.Ui.Item_Part_Content; [[the content part for list placeholder item.
+ content: Efl.Ui.Layout_Part_Content; [[the content part for list placeholder item.
the content part is empty slot for user customizing.
fill the place with container widget such as layout, box, table.]]
}
diff --git a/src/lib/elementary/efl_ui_list_private.h b/src/lib/elementary/efl_ui_list_private.h
deleted file mode 100644
index 409956dce1..0000000000
--- a/src/lib/elementary/efl_ui_list_private.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef EFL_UI_LIST_PRIVATE_H
-#define EFL_UI_LIST_PRIVATE_H
-
-#include "Elementary.h"
-
-typedef struct _Efl_Ui_List_Data
-{
- // Eo Objects
- Eo *box; /* Internal box for Efl.Pack support */
- Eo *pan; /* Internal pan for scroll */
- Eo *smanager; /* Scroll Manager for support scroll with pan */
-
- struct {
- Efl_Ui_List_Item *item; /* Scroll target item */
- double align; /* Item scroll aligned position.
- -1 is for default case of scroll in */
- Eina_Bool anim : 1; /* boolean data for animation on scroll */
- } scroll; /* Item scroll values for deferred operation */
-
- Eina_List *items; /* All item list for internal maintaining */
- Eina_List *selected; /* Selected items list */
- Efl_Ui_List_Item *last_selected; /* latest selected item */
-
- Efl_Ui_Select_Mode select_mode; /* Select mode for items
- with single or multiple seleciton */
-
- // Boolean Data
- Eina_Bool freeze_want : 1; /* Flag for Scroll freezing */
- Eina_Bool match_content_w: 1; /* Flag for size matching on content width.
- it will disable horizontal scroll */
- Eina_Bool match_content_h: 1; /* Flag for size matching on content height.
- it will disable vertical scroll */
- Eina_Bool pan_resized : 1; /* Flag for pan resized.
- This value is used for checking scroll is
- calculated after initialized */
-} Efl_Ui_List_Data;
-
-typedef struct _Item_Iterator
-{
- Eina_Iterator iterator;
- Eina_List *list;
- Eina_Iterator *real_iterator;
- Eo *object;
-} Item_Iterator;
-
-
-#define EFL_UI_LIST_DATA_GET(o, pd) \
- Efl_Ui_List_Data * pd = efl_data_scope_safe_get(o, EFL_UI_LIST_CLASS)
-
-#define EFL_UI_LIST_DATA_GET_OR_RETURN(o, ptr, ...) \
- EFL_UI_LIST_DATA_GET(o, ptr); \
- if (EINA_UNLIKELY(!ptr)) \
- { \
- ERR("No widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- return __VA_ARGS__; \
- }
-
-#define EFL_UI_LIST_CHECK(obj) \
- if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_LIST_CLASS))) \
- return
-
-#endif
diff --git a/src/lib/elementary/efl_ui_list_view.c b/src/lib/elementary/efl_ui_list_view.c
index 219d2aa151..96866393a4 100644
--- a/src/lib/elementary/efl_ui_list_view.c
+++ b/src/lib/elementary/efl_ui_list_view.c
@@ -46,6 +46,7 @@ static const Elm_Action key_actions[] = {
EOLIAN static void
_efl_ui_list_view_pan_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Pan_Data *psd)
{
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
evas_object_smart_changed(psd->wobj);
}
@@ -626,8 +627,6 @@ _efl_ui_list_view_efl_canvas_group_group_add(Eo *obj, Efl_Ui_List_View_Data *pd)
_efl_ui_list_view_bar_hide_cb, obj);
_efl_ui_list_view_edje_object_attach(obj);
-
- elm_layout_sizing_eval(obj);
}
EOLIAN static void
@@ -863,7 +862,7 @@ _efl_ui_list_view_efl_ui_list_view_model_min_size_set(Eo *obj, Efl_Ui_List_View_
pd->min.w = min.w;
pd->min.h = min.h;
- evas_object_size_hint_min_set(wd->resize_obj, pd->min.w, pd->min.h);
+ efl_gfx_hint_size_min_set(wd->resize_obj, EINA_SIZE2D(pd->min.w, pd->min.h));
efl_event_callback_call(pd->pan_obj, EFL_UI_PAN_EVENT_PAN_CONTENT_CHANGED, NULL);
}
@@ -905,9 +904,10 @@ _content_created(Eo *obj, void *data, const Eina_Value value)
Efl_Ui_List_View_Layout_Item *item = tracking->item;
Efl_Ui_List_View_Item_Event evt;
- eina_value_pget(&value, &item->layout);
+ if (eina_value_array_count(&value) != 1) return eina_value_error_init(EINVAL);
+ eina_value_array_get(&value, 0, &item->layout);
- evas_object_smart_member_add(item->layout, tracking->pd->pan_obj);
+ efl_canvas_group_member_add(tracking->pd->pan_obj, item->layout);
evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item);
if (_elm_config->atspi_mode)
@@ -943,6 +943,7 @@ EOLIAN static Efl_Ui_List_View_Layout_Item *
_efl_ui_list_view_efl_ui_list_view_model_realize(Eo *obj, Efl_Ui_List_View_Data *pd, Efl_Ui_List_View_Layout_Item *item)
{
Efl_Ui_List_View_Layout_Item_Tracking *tracking;
+ Efl_Model *childrens[1];
EINA_SAFETY_ON_NULL_RETURN_VAL(item->children, item);
if (!item->children) return item;
@@ -954,11 +955,14 @@ _efl_ui_list_view_efl_ui_list_view_model_realize(Eo *obj, Efl_Ui_List_View_Data
tracking->item = item;
tracking->pd = pd;
+ childrens[0] = item->children;
- item->layout_request = efl_ui_view_factory_create_with_event(pd->factory, item->children, obj);
+ item->layout_request = efl_ui_view_factory_create_with_event(pd->factory,
+ EINA_C_ARRAY_ITERATOR_NEW(childrens),
+ obj);
item->layout_request = efl_future_then(obj, item->layout_request,
.success = _content_created,
- .success_type = EINA_VALUE_TYPE_OBJECT,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
.data = tracking,
.free = _clean_request);
@@ -996,8 +1000,8 @@ _efl_ui_list_view_efl_ui_list_view_model_unrealize(Eo *obj, Efl_Ui_List_View_Dat
evt.index = efl_ui_list_view_item_index_get(item);
efl_event_callback_call(obj, EFL_UI_LIST_VIEW_EVENT_ITEM_UNREALIZED, &evt);
+ efl_canvas_group_member_remove(obj, pd->pan_obj);
efl_ui_factory_release(pd->factory, item->layout);
- evas_object_smart_member_del(item->layout);
item->layout = NULL;
}
diff --git a/src/lib/elementary/efl_ui_list_view.eo b/src/lib/elementary/efl_ui_list_view.eo
index b1560ef5ba..b5e15591a6 100644
--- a/src/lib/elementary/efl_ui_list_view.eo
+++ b/src/lib/elementary/efl_ui_list_view.eo
@@ -9,7 +9,7 @@ struct @beta Efl.Ui.List_View_Item_Event
}
class @beta Efl.Ui.List_View extends Efl.Ui.Layout_Base implements Efl.Ui.Scrollable_Interactive, Efl.Ui.Scrollbar,
Efl.Access.Widget.Action, Efl.Access.Selection, Efl.Ui.Focus.Composition, Efl.Ui.Focus.Manager_Sub,
- Efl.Ui.Selectable, Efl.Ui.List_View_Model, Efl.Ui.Widget_Focus_Manager
+ Efl.Ui.Container_Selectable, Efl.Ui.List_View_Model, Efl.Ui.Widget_Focus_Manager
{
methods {
@property homogeneous {
diff --git a/src/lib/elementary/efl_ui_list_view_precise_layouter.c b/src/lib/elementary/efl_ui_list_view_precise_layouter.c
index d20d706d3f..a7ee6ec102 100644
--- a/src/lib/elementary/efl_ui_list_view_precise_layouter.c
+++ b/src/lib/elementary/efl_ui_list_view_precise_layouter.c
@@ -65,7 +65,7 @@ _item_size_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Lay
efl_gfx_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
efl_gfx_hint_align_get(item->layout, &align[0], &align[1]);
efl_gfx_hint_fill_get(item->layout, &fill[0], &fill[1]);
- max = efl_gfx_hint_size_max_get(item->layout);
+ max = efl_gfx_hint_size_combined_max_get(item->layout);
// box outer margin
boxw -= boxl + boxr;
diff --git a/src/lib/elementary/efl_ui_multi_selectable.eo b/src/lib/elementary/efl_ui_multi_selectable.eo
new file mode 100644
index 0000000000..3957fe332e
--- /dev/null
+++ b/src/lib/elementary/efl_ui_multi_selectable.eo
@@ -0,0 +1,32 @@
+enum @beta Efl.Ui.Select_Mode {
+ [[Type of multi selectable object.]]
+ single, [[Only single child is selected. if the child is selected,
+ previous selected child will be unselected.]]
+ single_always, [[Same as single select except, this will be selected
+ in every select calls though child is already been selected.]]
+ multi, [[allow multiple selection of children.]]
+ none [[Last value of select mode. child cannot be selected at all.]]
+}
+
+interface @beta Efl.Ui.Multi_Selectable extends Efl.Ui.Single_Selectable
+{
+ [[Interface for getting access to a range of selected items.
+
+ The implementor of this interface provides the possibility to select multiple Selectables. (If not, only Efl.Ui.Single_Selectable should be implemented)]]
+ c_prefix: efl_ui;
+ methods
+ {
+ @property select_mode {
+ [[The mode type for children selection.]]
+ set {}
+ get {}
+ values {
+ mode: Efl.Ui.Select_Mode; [[Type of selection of children]]
+ }
+ }
+ selected_items_get {
+ [[Get the selected items in a iterator. The iterator sequence will be decided by selection.]]
+ return: iterator<Efl.Ui.Selectable> @owned @no_unused; [[User has to free the iterator after usage.]]
+ }
+ }
+}
diff --git a/src/lib/elementary/efl_ui_navigation_bar.c b/src/lib/elementary/efl_ui_navigation_bar.c
index 6c1de6773a..039b7f563f 100644
--- a/src/lib/elementary/efl_ui_navigation_bar.c
+++ b/src/lib/elementary/efl_ui_navigation_bar.c
@@ -48,7 +48,7 @@ _efl_ui_navigation_bar_efl_object_constructor(Eo *obj, Efl_Ui_Navigation_Bar_Dat
Eo *back_button = efl_add(EFL_UI_BUTTON_CLASS, obj,
elm_widget_element_update(obj, efl_added, "back_button"),
- efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _back_button_clicked_cb, obj),
+ efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED, _back_button_clicked_cb, obj),
efl_gfx_entity_visible_set(efl_added, EINA_FALSE));
pd->back_button = back_button;
@@ -182,7 +182,7 @@ _efl_ui_navigation_bar_part_back_button_efl_content_content_set(Eo *obj, void *_
if (content == ppd->back_button) return EINA_FALSE;
- efl_event_callback_add(content, EFL_UI_EVENT_CLICKED, _back_button_clicked_cb, pd->obj);
+ efl_event_callback_add(content, EFL_INPUT_EVENT_CLICKED, _back_button_clicked_cb, pd->obj);
ppd->back_button = content;
return _efl_ui_navigation_bar_content_set(pd->obj, ppd, pd->part, content);
@@ -203,7 +203,7 @@ _efl_ui_navigation_bar_part_back_button_efl_content_content_unset(Eo *obj, void
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd, NULL);
- efl_event_callback_del(ppd->back_button, EFL_UI_EVENT_CLICKED, _back_button_clicked_cb, pd->obj);
+ efl_event_callback_del(ppd->back_button, EFL_INPUT_EVENT_CLICKED, _back_button_clicked_cb, pd->obj);
ppd->back_button = NULL;
return _efl_ui_navigation_bar_content_unset(pd->obj, ppd, pd->part);
diff --git a/src/lib/elementary/efl_ui_pan.c b/src/lib/elementary/efl_ui_pan.c
index 534b433661..753793606d 100644
--- a/src/lib/elementary/efl_ui_pan.c
+++ b/src/lib/elementary/efl_ui_pan.c
@@ -147,6 +147,7 @@ _efl_ui_pan_content_resize_cb(void *data,
evas_object_smart_changed(pobj);
}
efl_event_callback_call(pobj, EFL_UI_PAN_EVENT_PAN_CONTENT_CHANGED, NULL);
+ efl_event_callback_call(pobj, EFL_UI_PAN_EVENT_PAN_POSITION_CHANGED, NULL);
}
EOLIAN static Eina_Bool
@@ -212,6 +213,7 @@ _efl_ui_pan_efl_content_content_unset(Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *pd)
EOLIAN static void
_efl_ui_pan_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *psd)
{
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
efl_gfx_entity_position_set(psd->content, EINA_POSITION2D(psd->x - psd->px, psd->y - psd->py));
}
#include "efl_ui_pan.eo.c"
diff --git a/src/lib/elementary/efl_ui_pan.eo b/src/lib/elementary/efl_ui_pan.eo
index 9923a39463..894fd719ad 100644
--- a/src/lib/elementary/efl_ui_pan.eo
+++ b/src/lib/elementary/efl_ui_pan.eo
@@ -1,39 +1,55 @@
class @beta Efl.Ui.Pan extends Efl.Canvas.Group implements Efl.Content
{
- [[Elementary pan class]]
+ [[Pan widget class.
+
+ This widget positions its contents (set using @Efl.Content.content) relative to the widget itself.
+ This is particularly useful for large content which does not fit inside its container. In this case
+ only a portion is shown.
+
+ The position of this "window" into the content can be changed using @Efl.Ui.Pan.pan_position.
+ This widget does not provide means for a user to change the content's position (like scroll bars).
+ This widget is meant to be used internally by other clases like @Efl.Ui.Scroll.Manager.
+ ]]
methods {
@property pan_position {
- [[Position]]
- set {
- }
- get {
- }
+ [[Position of the content inside the Pan widget.
+
+ Setting the position to @Efl.Ui.Pan.pan_position_min makes the upper left corner of the content visible.
+ Setting the position to @Efl.Ui.Pan.pan_position_max makes the lower right corner of the content visible.
+ Values outside this range are valid and make the background show.
+ ]]
values {
- position: Eina.Position2D;
+ position: Eina.Position2D; [[Content position.]]
}
}
@property content_size {
- [[Content size]]
+ [[Size of the content currently set through @Efl.Content.content.
+ This is a convenience proxy.
+ ]]
get {
}
values {
- size: Eina.Size2D;
+ size: Eina.Size2D; [[The size of the content.]]
}
}
@property pan_position_min {
- [[The minimal position to scroll]]
+ [[Position you can set to @Efl.Ui.Pan.pan_position so that the content's upper left corner is visible.
+ Always (0, 0).
+ ]]
get {
}
values {
- pos: Eina.Position2D;
+ pos: Eina.Position2D; [[Content's upper left corner position.]]
}
}
@property pan_position_max {
- [[The maximal position to scroll]]
+ [[Position you can set to @Efl.Ui.Pan.pan_position so that the content's lower right corner is visible.
+ It depends both on the content's size and this widget's size.
+ ]]
get {
}
values {
- pos: Eina.Position2D;
+ pos: Eina.Position2D; [[Content's lower right corner position.]]
}
}
}
@@ -48,8 +64,8 @@ class @beta Efl.Ui.Pan extends Efl.Canvas.Group implements Efl.Content
Efl.Canvas.Group.group_calculate;
}
events {
- pan,content,changed: void; [[Called when pan content changed]]
- pan,viewport,changed: void; [[Called when pan viewport changed]]
- pan,position,changed: void; [[Called when pan position changed]]
+ pan,content,changed: void; [[The content has changed.]]
+ pan,viewport,changed: void; [[This widget's position or size has changed.]]
+ pan,position,changed: void; [[The content's position has changed.]]
}
}
diff --git a/src/lib/elementary/efl_ui_panel.c b/src/lib/elementary/efl_ui_panel.c
index bfa7a9391d..489569b35c 100644
--- a/src/lib/elementary/efl_ui_panel.c
+++ b/src/lib/elementary/efl_ui_panel.c
@@ -6,6 +6,7 @@
#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
#define EFL_UI_FOCUS_LAYER_PROTECTED
#define EFL_PART_PROTECTED
+#define EFL_UI_SCROLL_MANAGER_PROTECTED
#include <Elementary.h>
@@ -53,24 +54,18 @@ _mirrored_set(Evas_Object *obj,
}
EOLIAN static void
-_efl_ui_panel_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Panel_Data *sd)
+_efl_ui_panel_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Panel_Data *sd)
{
- Evas_Coord mw = 0, mh = 0;
-
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- if (sd->delete_me) return;
+ if (sd->delete_me) return;
if (sd->scrollable)
{
- if (sd->hidden) _drawer_close(obj, wd->w, wd->h, EINA_FALSE);
- else _drawer_open(obj, wd->w, wd->h, EINA_FALSE);
+ Eina_Size2D size = efl_gfx_entity_size_get(obj);
+ if (sd->hidden) _drawer_close(obj, size.w, size.h, EINA_FALSE);
+ else _drawer_open(obj, size.w, size.h, EINA_FALSE);
}
- evas_object_smart_calculate(sd->bx);
- edje_object_size_min_calc(wd->resize_obj, &mw, &mh);
- evas_object_size_hint_min_set(obj, mw, mh);
- evas_object_size_hint_max_set(obj, -1, -1);
+ efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
}
static char *
@@ -233,15 +228,12 @@ _efl_ui_panel_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Panel_Data *sd)
evas_object_hide(sd->event);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- evas_object_size_hint_min_set(sd->event, minw, minh);
+ efl_gfx_hint_size_min_set(sd->event, EINA_SIZE2D(minw, minh));
if (edje_object_part_exists(wd->resize_obj, "efl.swallow.event"))
efl_content_set(efl_part(efl_super(obj, MY_CLASS), "efl.swallow.event"), sd->event);
}
- if (efl_finalized_get(obj))
- elm_layout_sizing_eval(obj);
-
return int_ret;
}
@@ -263,20 +255,20 @@ _handler_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
switch (sd->orient)
{
case EFL_UI_PANEL_ORIENT_TOP:
- elm_interface_scrollable_region_bring_in
- (obj, 0, (h * sd->content_size_ratio) - sd->handler_size, w, h);
+ efl_ui_scrollable_scroll
+ (obj, EINA_RECT(0, (h * sd->content_size_ratio) - sd->handler_size, w, h), EINA_TRUE);
break;
case EFL_UI_PANEL_ORIENT_BOTTOM:
- elm_interface_scrollable_region_bring_in
- (obj, 0, sd->handler_size, w, h);
+ efl_ui_scrollable_scroll
+ (obj, EINA_RECT(0, sd->handler_size, w, h), EINA_TRUE);
break;
case EFL_UI_PANEL_ORIENT_LEFT:
- elm_interface_scrollable_region_bring_in
- (obj, (w * sd->content_size_ratio) - sd->handler_size, 0, w, h);
+ efl_ui_scrollable_scroll
+ (obj, EINA_RECT((w * sd->content_size_ratio) - sd->handler_size, 0, w, h), EINA_TRUE);
break;
case EFL_UI_PANEL_ORIENT_RIGHT:
- elm_interface_scrollable_region_bring_in
- (obj, sd->handler_size, 0, w, h);
+ efl_ui_scrollable_scroll
+ (obj, EINA_RECT(sd->handler_size, 0, w, h), EINA_TRUE);
break;
}
}
@@ -289,8 +281,7 @@ _drawer_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
if (sd->freeze)
{
- elm_interface_scrollable_movement_block_set
- (obj, EFL_UI_SCROLL_BLOCK_NONE);
+ efl_ui_scrollable_movement_block_set(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
}
@@ -313,21 +304,16 @@ _drawer_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
x = w * sd->content_size_ratio;
break;
}
-
- if (anim)
- elm_interface_scrollable_region_bring_in
- (obj, x, y, w, h);
- else
- elm_interface_scrollable_content_region_show
- (obj, x, y, w, h);
+ efl_ui_scrollable_scroll(obj, EINA_RECT(x, y, w, h), anim);
}
static void
_drawer_close(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
{
EFL_UI_PANEL_DATA_GET(obj, sd);
- int x = 0, y = 0, cx, cy;
+ int x = 0, y = 0;
Eina_Bool horizontal = EINA_FALSE;
+ Eina_Position2D c;
elm_widget_tree_unfocusable_set(obj, EINA_TRUE);
switch (sd->orient)
@@ -352,17 +338,17 @@ _drawer_close(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
break;
}
- elm_interface_scrollable_content_pos_get(obj, &cx, &cy);
+ c = efl_ui_scrollable_content_pos_get(obj);
- if ((x == cx) && (y == cy))
+ if ((x == c.x) && (y == c.y))
{
if (!sd->freeze)
{
if (horizontal)
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
else
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
sd->freeze = EINA_TRUE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,hidden", "efl");
@@ -375,23 +361,23 @@ _drawer_close(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
{
if (sd->freeze)
{
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
}
- elm_interface_scrollable_region_bring_in(obj, x, y, w, h);
+ efl_ui_scrollable_scroll(obj, EINA_RECT(x, y, w, h), anim);
}
else
{
- elm_interface_scrollable_content_region_show(obj, x, y, w, h);
+ efl_ui_scrollable_scroll(obj, EINA_RECT(x, y, w, h), anim);
if (!sd->freeze)
{
if (horizontal)
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
else
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
sd->freeze = EINA_TRUE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,hidden", "efl");
@@ -455,6 +441,7 @@ _state_sync(Evas_Object *obj)
EFL_UI_PANEL_DATA_GET(obj, sd);
Evas_Coord pos, panel_size, w, h, threshold;
Eina_Bool horizontal = EINA_FALSE, reverse = EINA_FALSE;
+ Eina_Position2D c;
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
@@ -475,12 +462,13 @@ _state_sync(Evas_Object *obj)
break;
}
+ c = efl_ui_scrollable_content_pos_get(obj);
if (horizontal)
{
if (w <= 0) return EINA_TRUE;
panel_size = w * sd->content_size_ratio;
- elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
+ pos = c.x;
reverse ^= efl_ui_mirrored_get(obj);
}
else
@@ -488,7 +476,7 @@ _state_sync(Evas_Object *obj)
if (h <= 0) return EINA_TRUE;
panel_size = h * sd->content_size_ratio;
- elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
+ pos = c.y;
}
threshold = (sd->hidden) ? panel_size - (panel_size / 4) : (panel_size / 4);
@@ -517,7 +505,7 @@ _timer_cb(void *data)
if (sd->freeze)
{
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
@@ -625,7 +613,7 @@ _on_mouse_move(void *data,
case EFL_UI_PANEL_ORIENT_TOP:
if (sd->timer && ((cur_y - sd->down_y) > finger_size))
{
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
@@ -634,7 +622,7 @@ _on_mouse_move(void *data,
case EFL_UI_PANEL_ORIENT_BOTTOM:
if (sd->timer && ((sd->down_y - cur_y) > finger_size))
{
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
@@ -644,7 +632,7 @@ _on_mouse_move(void *data,
if ((!is_mirrored && (sd->timer) && ((cur_x - sd->down_x) > finger_size)) ||
((is_mirrored) && (sd->timer) && ((sd->down_x - cur_x) > finger_size)))
{
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
@@ -654,7 +642,7 @@ _on_mouse_move(void *data,
if ((is_mirrored && (sd->timer) && ((cur_x - sd->down_x) > finger_size)) ||
(!is_mirrored && (sd->timer) && ((sd->down_x - cur_x) > finger_size)))
{
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
@@ -740,8 +728,7 @@ _efl_ui_panel_efl_content_content_set(Eo *obj, Efl_Ui_Panel_Data *sd, Efl_Gfx_En
elm_widget_sub_object_add(sd->scr_ly, sd->content);
}
efl_event_callback_call(obj, EFL_CONTENT_EVENT_CONTENT_CHANGED, content);
- if (efl_alive_get(obj))
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
return EINA_TRUE;
}
@@ -760,16 +747,6 @@ _efl_ui_panel_efl_content_content_unset(Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *
return ret;
}
-EOLIAN static void
-_efl_ui_panel_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Position2D pos)
-{
- if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
- return;
-
- efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
- efl_gfx_entity_position_set(sd->hit_rect, pos);
-}
-
static void
_scrollable_layout_resize(Eo *obj, Efl_Ui_Panel_Data *sd, Evas_Coord w, Evas_Coord h)
{
@@ -779,19 +756,18 @@ _scrollable_layout_resize(Eo *obj, Efl_Ui_Panel_Data *sd, Evas_Coord w, Evas_Coo
case EFL_UI_PANEL_ORIENT_BOTTOM:
// vertical
evas_object_resize(sd->scr_ly, w, (1 + sd->content_size_ratio) * h);
- evas_object_size_hint_min_set(sd->scr_panel, w, (sd->content_size_ratio * h));
- evas_object_size_hint_min_set(sd->scr_event, w, h);
+ efl_gfx_hint_size_min_set(sd->scr_panel, EINA_SIZE2D(w, (sd->content_size_ratio * h)));
+ efl_gfx_hint_size_min_set(sd->scr_event, EINA_SIZE2D(w, h));
break;
case EFL_UI_PANEL_ORIENT_LEFT:
case EFL_UI_PANEL_ORIENT_RIGHT:
// horizontal
evas_object_resize(sd->scr_ly, (1 + sd->content_size_ratio) * w, h);
- evas_object_size_hint_min_set(sd->scr_panel, (sd->content_size_ratio * w), h);
- evas_object_size_hint_min_set(sd->scr_event, w, h);
+ efl_gfx_hint_size_min_set(sd->scr_panel, EINA_SIZE2D((sd->content_size_ratio * w), h));
+ efl_gfx_hint_size_min_set(sd->scr_event, EINA_SIZE2D(w, h));
break;
}
- if (efl_finalized_get(obj))
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
}
EOLIAN static void
@@ -804,7 +780,6 @@ _efl_ui_panel_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Size2
if (!sd->scrollable) return;
- efl_gfx_entity_size_set(sd->hit_rect, sz);
_scrollable_layout_resize(obj, sd, sz.w, sz.h);
}
@@ -813,7 +788,7 @@ _efl_ui_panel_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_Panel_Data *sd,
{
efl_canvas_group_member_add(efl_super(obj, MY_CLASS), member);
- if (sd->hit_rect) evas_object_raise(sd->hit_rect);
+ if (sd->scr_event) evas_object_raise(sd->scr_event);
}
EOLIAN static void
@@ -868,6 +843,9 @@ _efl_ui_panel_efl_object_constructor(Eo *obj, Efl_Ui_Panel_Data *_pd)
else
{
elm_layout_content_set(obj, "efl.content", _pd->bx);
+ /* trigger box recalc on manual panel calc */
+ _efl_ui_layout_subobjs_calc_set(obj, EINA_TRUE);
+ efl_ui_layout_finger_size_multiplier_set(obj, 0, 0);
if (edje_object_part_exists
(wd->resize_obj, "efl.swallow.event"))
@@ -875,7 +853,7 @@ _efl_ui_panel_efl_object_constructor(Eo *obj, Efl_Ui_Panel_Data *_pd)
Evas_Coord minw = 0, minh = 0;
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- evas_object_size_hint_min_set(_pd->event, minw, minh);
+ efl_gfx_hint_size_min_set(_pd->event, EINA_SIZE2D(minw, minh));
efl_content_set(efl_part(efl_super(obj, MY_CLASS), "efl.swallow.event"), _pd->event);
}
}
@@ -931,12 +909,12 @@ _efl_ui_panel_orient_set(Eo *obj, Efl_Ui_Panel_Data *sd, Efl_Ui_Panel_Orient ori
{
case EFL_UI_PANEL_ORIENT_TOP:
case EFL_UI_PANEL_ORIENT_BOTTOM:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
break;
case EFL_UI_PANEL_ORIENT_LEFT:
case EFL_UI_PANEL_ORIENT_RIGHT:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
break;
}
@@ -950,8 +928,7 @@ _efl_ui_panel_orient_set(Eo *obj, Efl_Ui_Panel_Data *sd, Efl_Ui_Panel_Orient ori
else
_orient_set_do(obj);
- if (efl_finalized_get(obj))
- elm_layout_sizing_eval(obj);
+ efl_canvas_group_change(obj);
}
EOLIAN static Efl_Ui_Panel_Orient
@@ -993,8 +970,9 @@ EOLIAN static Eina_Rect
_efl_ui_panel_efl_ui_widget_interest_region_get(const Eo *obj, Efl_Ui_Panel_Data *sd)
{
Eina_Rect r = {};
+ Eina_Position2D p;
- elm_interface_scrollable_content_pos_get(obj, &r.x, &r.y);
+ p = efl_ui_scrollable_content_pos_get(obj);
evas_object_geometry_get(obj, NULL, NULL, &r.w, &r.h);
switch (sd->orient)
{
@@ -1009,17 +987,21 @@ _efl_ui_panel_efl_ui_widget_interest_region_get(const Eo *obj, Efl_Ui_Panel_Data
}
if (r.w < 1) r.w = 1;
if (r.h < 1) r.h = 1;
+ r.x = p.x;
+ r.y = p.y;
return r;
}
static void
-_anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
+_anim_stop_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
+ Eo *obj = event->object;
EFL_UI_PANEL_DATA_GET(obj, sd);
Evas_Object *ao;
Evas_Coord pos, w, h, panel_size = 0;
Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE, reverse = EINA_FALSE;
+ Eina_Position2D c;
if (elm_widget_disabled_get(obj)) return;
@@ -1038,13 +1020,14 @@ _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
break;
}
+ c = efl_ui_scrollable_content_pos_get(obj);
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
if (horizontal)
{
if (w <= 0) return;
panel_size = w * sd->content_size_ratio;
- elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
+ pos = c.x;
reverse ^= efl_ui_mirrored_get(obj);
}
else
@@ -1052,7 +1035,7 @@ _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
if (h <= 0) return;
panel_size = h * sd->content_size_ratio;
- elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
+ pos = c.y;
}
if (pos == 0) open = !reverse;
@@ -1061,9 +1044,6 @@ _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
if (open)
{
- elm_interface_scrollable_single_direction_set
- (obj, ELM_SCROLLER_SINGLE_DIRECTION_HARD);
-
//focus & access
elm_object_tree_focus_allow_set(obj, EINA_TRUE);
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
@@ -1078,17 +1058,14 @@ _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
else
{
if (horizontal)
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
else
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
sd->freeze = EINA_TRUE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,hidden", "efl");
- elm_interface_scrollable_single_direction_set
- (obj, ELM_SCROLLER_SINGLE_DIRECTION_NONE);
-
//focus & access
elm_object_tree_focus_allow_set(obj, EINA_FALSE);
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
@@ -1100,63 +1077,21 @@ _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
}
static void
-_scroll_cb(Evas_Object *obj, void *data EINA_UNUSED)
+_scroll_cb(void *data EINA_UNUSED, const Efl_Event *event_info EINA_UNUSED)
{
+ Eo *obj = event_info->object;
EFL_UI_PANEL_DATA_GET(obj, sd);
- Efl_Ui_Panel_Scroll_Info event;
- Evas_Coord x, y, w, h;
if (elm_widget_disabled_get(obj)) return;
// in the case of
// freeze_set(FALSE) -> mouse_up -> freeze_set(TRUE) -> scroll
if (sd->freeze)
{
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_NONE);
sd->freeze = EINA_FALSE;
elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
}
-
- elm_interface_scrollable_content_pos_get(obj, &x, &y);
- evas_object_geometry_get(obj, NULL, NULL, &w, &h);
-
- switch (sd->orient)
- {
- case EFL_UI_PANEL_ORIENT_TOP:
- event.rel_x = 1;
- event.rel_y = 1 - ((double) y / (double) ((sd->content_size_ratio) * h));
- break;
- case EFL_UI_PANEL_ORIENT_BOTTOM:
- event.rel_x = 1;
- event.rel_y = (double) y / (double) ((sd->content_size_ratio) * h);
- break;
- case EFL_UI_PANEL_ORIENT_LEFT:
- if (!efl_ui_mirrored_get(obj))
- {
- event.rel_x = 1 - ((double) x / (double) ((sd->content_size_ratio) * w));
- event.rel_y = 1;
- }
- else
- {
- event.rel_x = (double) x / (double) ((sd->content_size_ratio) * w);
- event.rel_y = 1;
- }
- break;
- case EFL_UI_PANEL_ORIENT_RIGHT:
- if (efl_ui_mirrored_get(obj))
- {
- event.rel_x = 1 - ((double) x / (double) ((sd->content_size_ratio) * w));
- event.rel_y = 1;
- }
- else
- {
- event.rel_x = (double) x / (double) ((sd->content_size_ratio) * w);
- event.rel_y = 1;
- }
- break;
- }
- efl_event_callback_legacy_call
- (obj, EFL_UI_EVENT_SCROLL, (void *) &event);
}
EOLIAN static void
@@ -1172,13 +1107,13 @@ _efl_ui_panel_efl_ui_widget_disabled_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bo
{
case ELM_PANEL_ORIENT_BOTTOM:
case ELM_PANEL_ORIENT_TOP:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
break;
case ELM_PANEL_ORIENT_RIGHT:
case ELM_PANEL_ORIENT_LEFT:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
break;
}
@@ -1200,13 +1135,13 @@ _efl_ui_panel_efl_ui_widget_disabled_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bo
{
case ELM_PANEL_ORIENT_BOTTOM:
case ELM_PANEL_ORIENT_TOP:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
break;
case ELM_PANEL_ORIENT_RIGHT:
case ELM_PANEL_ORIENT_LEFT:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
break;
}
@@ -1287,29 +1222,33 @@ _efl_ui_panel_scrollable_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool scrollabl
elm_widget_resize_object_set(obj, sd->scr_edje);
- if (!sd->hit_rect)
+ if (!sd->smanager)
{
- sd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
- evas_object_smart_member_add(sd->hit_rect, obj);
- elm_widget_sub_object_add(obj, sd->hit_rect);
- evas_object_color_set(sd->hit_rect, 0, 0, 0, 0);
- evas_object_show(sd->hit_rect);
- evas_object_repeat_events_set(sd->hit_rect, EINA_TRUE);
-
- elm_interface_scrollable_objects_set(obj, sd->scr_edje, sd->hit_rect);
- elm_interface_scrollable_animate_stop_cb_set(obj, _anim_stop_cb);
- elm_interface_scrollable_scroll_cb_set(obj, _scroll_cb);
+ sd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
+ efl_ui_mirrored_set(sd->smanager, efl_ui_mirrored_get(obj));
+
+ efl_event_callback_add(obj, EFL_UI_EVENT_SCROLL_ANIM_STOP, _anim_stop_cb, NULL);
+ efl_event_callback_add(obj, EFL_UI_EVENT_SCROLL, _scroll_cb, NULL);
+ }
+
+ efl_composite_attach(obj, sd->smanager);
+ efl_ui_scroll_connector_bind(obj, sd->smanager);
+
+ if (!sd->pan_obj)
+ {
+ sd->pan_obj = efl_add(EFL_UI_PAN_CLASS, obj);
+ efl_ui_scroll_manager_pan_set(sd->smanager, sd->pan_obj);
+ efl_content_set(efl_part(sd->scr_edje, "efl.content"), sd->pan_obj);
}
if (!sd->scr_ly)
{
sd->scr_ly = efl_add(EFL_UI_LAYOUT_CLASS, obj,
- elm_layout_theme_set(efl_added,
- "panel",
- "scrollable/left",
- elm_widget_style_get(obj)));
+ efl_ui_layout_theme_set(efl_added,
+ "panel", "scrollable/left",
+ efl_ui_widget_style_get(obj)));
- evas_object_smart_member_add(sd->scr_ly, obj);
+ efl_canvas_group_member_add(obj, sd->scr_ly);
elm_widget_sub_object_add(obj, sd->scr_ly);
_scrollable_layout_theme_set(obj, sd);
@@ -1326,7 +1265,7 @@ _efl_ui_panel_scrollable_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool scrollabl
elm_layout_content_set(sd->scr_ly, "event_area", sd->scr_event);
}
- elm_interface_scrollable_content_set(obj, sd->scr_ly);
+ efl_content_set(sd->pan_obj, sd->scr_ly);
sd->freeze = EINA_TRUE;
efl_content_set(efl_part(sd->scr_ly, "efl.content"), sd->bx);
if (sd->content) elm_widget_sub_object_add(sd->scr_ly, sd->content);
@@ -1335,19 +1274,16 @@ _efl_ui_panel_scrollable_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool scrollabl
{
case EFL_UI_PANEL_ORIENT_TOP:
case EFL_UI_PANEL_ORIENT_BOTTOM:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
break;
case EFL_UI_PANEL_ORIENT_LEFT:
case EFL_UI_PANEL_ORIENT_RIGHT:
- elm_interface_scrollable_movement_block_set
+ efl_ui_scrollable_movement_block_set
(obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
break;
}
- elm_interface_scrollable_single_direction_set
- (obj, ELM_SCROLLER_SINGLE_DIRECTION_NONE);
-
if (!elm_widget_disabled_get(obj) && !sd->callback_added)
{
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
@@ -1365,7 +1301,8 @@ _efl_ui_panel_scrollable_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool scrollabl
}
else
{
- elm_interface_scrollable_content_set(obj, NULL);
+ efl_ui_scroll_connector_unbind(obj);
+ efl_composite_detach(obj, sd->smanager);
if (sd->callback_added)
{
@@ -1410,7 +1347,4 @@ _efl_ui_panel_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED
/* Internal EO APIs and hidden overrides */
-#define EFL_UI_PANEL_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_panel)
-
#include "efl_ui_panel.eo.c"
diff --git a/src/lib/elementary/efl_ui_panel.eo b/src/lib/elementary/efl_ui_panel.eo
index fffe726ccb..3868949801 100644
--- a/src/lib/elementary/efl_ui_panel.eo
+++ b/src/lib/elementary/efl_ui_panel.eo
@@ -15,7 +15,7 @@ struct @beta Efl.Ui.Panel_Scroll_Info
rel_y: double; [[content scrolled position (0.0 ~ 1.0) in the panel]]
}
-class @beta Efl.Ui.Panel extends Efl.Ui.Layout_Base implements Efl.Ui.Focus.Layer, Elm.Interface_Scrollable, Efl.Content,
+class @beta Efl.Ui.Panel extends Efl.Ui.Layout_Base implements Efl.Ui.Focus.Layer, Efl.Ui.Scrollable_Interactive, Efl.Content,
Efl.Access.Widget.Action
{
[[Elementary panel class]]
@@ -76,9 +76,9 @@ class @beta Efl.Ui.Panel extends Efl.Ui.Layout_Base implements Efl.Ui.Focus.Laye
implements {
Efl.Object.constructor;
Efl.Object.destructor;
- Efl.Gfx.Entity.position { set; }
Efl.Gfx.Entity.size { set; }
Efl.Canvas.Group.group_member_add;
+ Efl.Canvas.Group.group_calculate;
Efl.Ui.Widget.theme_apply;
Efl.Ui.Widget.disabled {set;}
Efl.Ui.Widget.on_access_update;
@@ -92,4 +92,7 @@ class @beta Efl.Ui.Panel extends Efl.Ui.Layout_Base implements Efl.Ui.Focus.Laye
events {
toggled: void; [[Called when the hidden state was toggled]]
}
+ composite {
+ Efl.Ui.Scrollable_Interactive;
+ }
}
diff --git a/src/lib/elementary/efl_ui_panel_private.h b/src/lib/elementary/efl_ui_panel_private.h
index 18a32735b3..f1c3b93ae5 100644
--- a/src/lib/elementary/efl_ui_panel_private.h
+++ b/src/lib/elementary/efl_ui_panel_private.h
@@ -31,8 +31,9 @@ struct _Efl_Ui_Panel_Data
Evas_Object *bx, *content;
Evas_Object *event;
Evas_Object *scr_ly;
- Evas_Object *hit_rect, *panel_edje, *scr_edje;
+ Evas_Object *panel_edje, *scr_edje;
Evas_Object *scr_panel, *scr_event;
+ Evas_Object *smanager, *pan_obj;
Efl_Ui_Panel_Orient orient;
diff --git a/src/lib/elementary/efl_ui_panes.c b/src/lib/elementary/efl_ui_panes.c
index 7069e3edb5..3b6db20f40 100644
--- a/src/lib/elementary/efl_ui_panes.c
+++ b/src/lib/elementary/efl_ui_panes.c
@@ -6,7 +6,7 @@
#define ELM_LAYOUT_PROTECTED
#define EFL_GFX_HINT_PROTECTED
#define EFL_PART_PROTECTED
-#define EFL_UI_CLICKABLE_PROTECTED
+#define EFL_INPUT_CLICKABLE_PROTECTED
#include <Elementary.h>
@@ -129,7 +129,7 @@ _efl_ui_panes_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Panes_Data *sd)
evas_object_hide(sd->event);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- evas_object_size_hint_min_set(sd->event, minw, minh);
+ efl_gfx_hint_size_min_set(sd->event, EINA_SIZE2D(minw, minh));
int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
@@ -150,8 +150,6 @@ _efl_ui_panes_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Panes_Data *sd)
elm_layout_signal_emit(obj, "efl,panes,fixed", "efl");
}
- elm_layout_sizing_eval(obj);
-
elm_panes_content_left_size_set(obj, size);
return int_ret;
@@ -184,7 +182,7 @@ _on_pressed(void *data,
const char *source EINA_UNUSED)
{
efl_event_callback_legacy_call(data, ELM_PANES_EVENT_PRESS, NULL);
- efl_ui_clickable_press(data, 1);
+ efl_input_clickable_press(data, 1);
}
static void
@@ -195,7 +193,7 @@ _on_unpressed(void *data,
{
EFL_UI_PANES_DATA_GET(data, sd);
efl_event_callback_legacy_call(data, ELM_PANES_EVENT_UNPRESS, NULL);
- efl_ui_clickable_unpress(data, 1);
+ efl_input_clickable_unpress(data, 1);
if (sd->double_clicked)
{
evas_object_smart_callback_call(data, "clicked,double", NULL);
@@ -204,13 +202,14 @@ _on_unpressed(void *data,
}
EOLIAN static void
-_efl_ui_panes_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Panes_Data *sd)
+_efl_ui_panes_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Panes_Data *sd)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
Eo *first_content, *second_content;
Eina_Size2D min;
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
if (elm_widget_is_legacy(obj))
{
first_content = efl_content_get(efl_part(obj, "elm.swallow.left"));
@@ -439,7 +438,7 @@ _efl_ui_panes_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Panes_Data *_pd EINA_UN
}
else
{
- efl_ui_clickable_util_bind_to_theme(wd->resize_obj, obj);
+ efl_ui_action_connector_bind_clickable_to_theme(wd->resize_obj, obj);
}
evas_object_event_callback_add
(wd->resize_obj, EVAS_CALLBACK_RESIZE,
@@ -469,7 +468,7 @@ _efl_ui_panes_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Panes_Data *_pd EINA_UN
Evas_Coord minw = 0, minh = 0;
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- evas_object_size_hint_min_set(sd->event, minw, minh);
+ efl_gfx_hint_size_min_set(sd->event, EINA_SIZE2D(minw, minh));
elm_layout_content_set(obj, "elm.swallow.event", sd->event);
}
}
@@ -481,13 +480,11 @@ _efl_ui_panes_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Panes_Data *_pd EINA_UN
Evas_Coord minw = 0, minh = 0;
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- evas_object_size_hint_min_set(sd->event, minw, minh);
+ efl_gfx_hint_size_min_set(sd->event, EINA_SIZE2D(minw, minh));
elm_layout_content_set(obj, "efl.event", sd->event);
}
}
elm_widget_sub_object_add(obj, sd->event);
-
- elm_layout_sizing_eval(obj);
}
EOLIAN static Eo *
@@ -628,13 +625,13 @@ _efl_ui_panes_part_hint_min_allow_set(Eo *obj, void *_pd EINA_UNUSED, Eina_Bool
{
if (sd->first_hint_min_allow == allow) return;
sd->first_hint_min_allow = allow;
- elm_layout_sizing_eval(pd->obj);
+ efl_canvas_group_change(pd->obj);
}
else if (!strcmp(pd->part, "second"))
{
if (sd->second_hint_min_allow == allow) return;
sd->second_hint_min_allow = allow;
- elm_layout_sizing_eval(pd->obj);
+ efl_canvas_group_change(pd->obj);
}
}
@@ -702,8 +699,7 @@ ELM_LAYOUT_CONTENT_ALIASES_IMPLEMENT(efl_ui_panes)
#define EFL_UI_PANES_EXTRA_OPS \
EFL_CANVAS_GROUP_ADD_OPS(efl_ui_panes), \
- ELM_LAYOUT_CONTENT_ALIASES_OPS(efl_ui_panes), \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_panes)
+ ELM_LAYOUT_CONTENT_ALIASES_OPS(efl_ui_panes)
#include "efl_ui_panes.eo.c"
#include "efl_ui_panes_eo.legacy.c"
diff --git a/src/lib/elementary/efl_ui_panes.eo b/src/lib/elementary/efl_ui_panes.eo
index a9c2bbd089..0194fe0ec1 100644
--- a/src/lib/elementary/efl_ui_panes.eo
+++ b/src/lib/elementary/efl_ui_panes.eo
@@ -1,5 +1,5 @@
class @beta Efl.Ui.Panes extends Efl.Ui.Layout_Base implements Efl.Ui.Layout_Orientable,
- Efl.Ui.Clickable
+ Efl.Input.Clickable
{
[[Elementary panes class]]
event_prefix: elm_panes;
@@ -47,6 +47,7 @@ class @beta Efl.Ui.Panes extends Efl.Ui.Layout_Base implements Efl.Ui.Layout_Ori
}
implements {
Efl.Object.constructor;
+ Efl.Canvas.Group.group_calculate;
Efl.Ui.Widget.theme_apply;
Efl.Ui.Layout_Orientable.orientation { get; set; [[Only supports $vertical and $horizontal. Default is $vertical.]] }
Efl.Part.part_get;
diff --git a/src/lib/elementary/efl_ui_panes_legacy_eo.c b/src/lib/elementary/efl_ui_panes_legacy_eo.c
index ba95585085..b4fd1a8844 100644
--- a/src/lib/elementary/efl_ui_panes_legacy_eo.c
+++ b/src/lib/elementary/efl_ui_panes_legacy_eo.c
@@ -32,4 +32,4 @@ static const Efl_Class_Description _efl_ui_panes_legacy_class_desc = {
NULL
};
-EFL_DEFINE_CLASS(efl_ui_panes_legacy_class_get, &_efl_ui_panes_legacy_class_desc, EFL_UI_PANES_CLASS, EFL_UI_LEGACY_INTERFACE, NULL);
+EFL_DEFINE_CLASS(efl_ui_panes_legacy_class_get, &_efl_ui_panes_legacy_class_desc, EFL_UI_PANES_CLASS, ELM_LAYOUT_MIXIN, EFL_UI_LEGACY_INTERFACE, NULL);
diff --git a/src/lib/elementary/efl_ui_popup.c b/src/lib/elementary/efl_ui_popup.c
index 341de7e750..c29b3f2fc8 100644
--- a/src/lib/elementary/efl_ui_popup.c
+++ b/src/lib/elementary/efl_ui_popup.c
@@ -19,23 +19,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)
{
Efl_Ui_Popup_Data *pd = efl_data_scope_get(obj, MY_CLASS);
@@ -74,12 +57,300 @@ _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_UNUSED, Eina_Size2D size)
+_efl_ui_popup_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Popup_Data *pd, Eina_Size2D size)
{
efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), size);
- elm_layout_sizing_eval(obj);
+ if (!pd->in_calc)
+ efl_canvas_group_change(obj);
}
static void
@@ -89,15 +360,31 @@ _parent_geom_cb(void *data, const Efl_Event *ev EINA_UNUSED)
EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, pd);
- //Add align calc only
- Eina_Bool needs_size_calc = pd->needs_size_calc;
- elm_layout_sizing_eval(obj);
- pd->needs_size_calc = needs_size_calc;
+ efl_canvas_group_change(obj);
+}
+
+static void
+_hints_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Efl_Ui_Popup_Data *pd = data;
+
+ if (!pd->in_calc)
+ efl_canvas_group_change(ev->object);
}
EOLIAN static void
-_efl_ui_popup_efl_ui_widget_widget_parent_set(Eo *obj, Efl_Ui_Popup_Data *pd EINA_UNUSED, Eo *parent EINA_UNUSED)
+_efl_ui_popup_efl_ui_widget_widget_parent_set(Eo *obj, Efl_Ui_Popup_Data *pd, Eo *parent)
{
+ if (!parent)
+ {
+ /* unsetting parent, probably before deletion */
+ if (pd->win_parent)
+ {
+ efl_event_callback_del(pd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _parent_geom_cb, obj);
+ efl_event_callback_del(pd->win_parent, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _parent_geom_cb, obj);
+ }
+ goto end;
+ }
pd->win_parent = efl_provider_find(obj, EFL_UI_WIN_CLASS);
if (!pd->win_parent)
{
@@ -112,7 +399,7 @@ _efl_ui_popup_efl_ui_widget_widget_parent_set(Eo *obj, Efl_Ui_Popup_Data *pd EIN
efl_event_callback_add(pd->win_parent, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _parent_geom_cb, obj);
efl_event_callback_add(pd->win_parent, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _parent_geom_cb, obj);
-
+end:
efl_ui_widget_parent_set(efl_super(obj, MY_CLASS), parent);
}
@@ -121,10 +408,7 @@ _efl_ui_popup_align_set(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Data *pd, Efl_Ui_Popup
{
pd->align = type;
- //Add align calc only
- Eina_Bool needs_size_calc = pd->needs_size_calc;
- elm_layout_sizing_eval(obj);
- pd->needs_size_calc = needs_size_calc;
+ efl_canvas_group_change(obj);
}
EOLIAN static Efl_Ui_Popup_Align
@@ -133,18 +417,6 @@ _efl_ui_popup_align_get(const Eo *obj EINA_UNUSED, Efl_Ui_Popup_Data *pd)
return pd->align;
}
-EOLIAN static void
-_efl_ui_popup_popup_size_set(Eo *obj, Efl_Ui_Popup_Data *pd EINA_UNUSED, Eina_Size2D size)
-{
- efl_gfx_entity_size_set(obj, size);
-}
-
-EOLIAN static Eina_Size2D
-_efl_ui_popup_popup_size_get(const Eo *obj, Efl_Ui_Popup_Data *pd EINA_UNUSED)
-{
- return efl_gfx_entity_size_get(obj);
-}
-
static Eina_Bool
_timer_cb(void *data)
{
@@ -216,6 +488,7 @@ _efl_ui_popup_efl_object_constructor(Eo *obj, Efl_Ui_Popup_Data *pd)
elm_widget_theme_klass_set(obj, "popup");
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
+ efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _hints_changed_cb, pd);
elm_widget_can_focus_set(obj, EINA_TRUE);
if (elm_widget_theme_object_set(obj, wd->resize_obj,
@@ -234,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;
}
@@ -241,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);
@@ -253,69 +532,43 @@ _efl_ui_popup_efl_object_destructor(Eo *obj, Efl_Ui_Popup_Data *pd)
static void
_sizing_eval(Eo *obj)
{
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- Evas_Coord minw = -1, minh = -1;
+ Eina_Size2D min;
- elm_coords_finger_size_adjust(1, &minw, 1, &minh);
- edje_object_size_min_restricted_calc
- (wd->resize_obj, &minw, &minh, minw, minh);
- efl_gfx_hint_size_min_set(obj, EINA_SIZE2D(minw, minh));
+ /* trigger layout calc */
+ efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
+ min = efl_gfx_hint_size_combined_min_get(obj);
Eina_Size2D size = efl_gfx_entity_size_get(obj);
Eina_Size2D new_size;
- new_size.w = (minw > size.w ? minw : size.w);
- new_size.h = (minh > size.h ? minh : size.h);
+ new_size.w = (min.w > size.w ? min.w : size.w);
+ new_size.h = (min.h > size.h ? min.h : size.h);
efl_gfx_entity_size_set(obj, new_size);
}
EOLIAN static void
-_efl_ui_popup_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Popup_Data *pd)
-{
- if (pd->needs_group_calc) return;
- pd->needs_group_calc = EINA_TRUE;
-
- /* These flags can be modified by sub classes not to calculate size or align
- * their super classes.
- * e.g. Efl.Ui.Popup.Alert.Scroll class sets the flag as follows not to
- * calculate size by its super class.
- *
- * ppd->needs_size_calc = EINA_FALSE;
- * efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
- */
- pd->needs_size_calc = EINA_TRUE;
- pd->needs_align_calc = EINA_TRUE;
-
- evas_object_smart_changed(obj);
-}
-
-EOLIAN static void
_efl_ui_popup_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Popup_Data *pd)
{
- /* When elm_layout_sizing_eval() is called, just flag is set instead of size
+ /* When efl_canvas_group_change() is called, just flag is set instead of size
* calculation.
* The actual size calculation is done here when the object is rendered to
* avoid duplicate size calculations. */
- if (pd->needs_group_calc)
+ efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
+ if (!pd->in_calc)
{
- if (pd->needs_size_calc)
- {
- _sizing_eval(obj);
- pd->needs_size_calc = EINA_FALSE;
- }
- if (pd->needs_align_calc)
- {
- _calc_align(obj);
- pd->needs_align_calc = EINA_FALSE;
- }
-
- Eina_Rect p_geom = efl_gfx_entity_geometry_get(pd->win_parent);
+ pd->in_calc = EINA_TRUE;
+ _sizing_eval(obj);
+ pd->in_calc = EINA_FALSE;
+ }
+ if (pd->anchor)
+ _anchor_calc(obj);
+ else
+ _calc_align(obj);
- efl_gfx_entity_position_set(pd->backwall, EINA_POSITION2D(0, 0));
- efl_gfx_entity_size_set(pd->backwall, EINA_SIZE2D(p_geom.w, p_geom.h));
+ Eina_Rect p_geom = efl_gfx_entity_geometry_get(pd->win_parent);
- pd->needs_group_calc = EINA_FALSE;
- }
+ efl_gfx_entity_position_set(pd->backwall, EINA_POSITION2D(0, 0));
+ efl_gfx_entity_size_set(pd->backwall, EINA_SIZE2D(p_geom.w, p_geom.h));
}
/* Standard widget overrides */
@@ -351,6 +604,42 @@ _efl_ui_popup_part_backwall_repeat_events_get(const Eo *obj, void *_pd EINA_UNUS
return efl_canvas_object_repeat_events_get(sd->backwall);
}
+EOLIAN static Eina_Stringshare *
+_efl_ui_popup_part_backwall_efl_file_file_get(const Eo *obj, void *_pd EINA_UNUSED)
+{
+ Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ Efl_Ui_Popup_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_POPUP_CLASS);
+
+ Eo *content = edje_object_part_swallow_get(sd->backwall, "efl.content");
+ return content ? efl_file_get(content) : NULL;
+}
+
+EOLIAN static Eina_Stringshare *
+_efl_ui_popup_part_backwall_efl_file_key_get(const Eo *obj, void *_pd EINA_UNUSED)
+{
+ Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ Efl_Ui_Popup_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_POPUP_CLASS);
+
+ Eo *content = edje_object_part_swallow_get(sd->backwall, "efl.content");
+ return content ? efl_file_key_get(content) : NULL;
+}
+
+EOLIAN static void
+_efl_ui_popup_part_backwall_efl_file_unload(Eo *obj, void *_pd EINA_UNUSED)
+{
+ Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ Efl_Ui_Popup_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_POPUP_CLASS);
+
+ efl_file_unload(efl_super(obj, EFL_UI_POPUP_PART_BACKWALL_CLASS));
+ Eo *prev_obj = edje_object_part_swallow_get(sd->backwall, "efl.content");
+ if (prev_obj)
+ {
+ edje_object_signal_emit(sd->backwall, "efl,state,content,unset", "efl");
+ edje_object_part_unswallow(sd->backwall, prev_obj);
+ efl_del(prev_obj);
+ }
+}
+
EOLIAN static Eina_Error
_efl_ui_popup_part_backwall_efl_file_load(Eo *obj, void *_pd EINA_UNUSED)
{
@@ -361,7 +650,7 @@ _efl_ui_popup_part_backwall_efl_file_load(Eo *obj, void *_pd EINA_UNUSED)
if (efl_file_loaded_get(obj)) return 0;
- err = efl_file_load(efl_super(obj, MY_CLASS));
+ err = efl_file_load(efl_super(obj, EFL_UI_POPUP_PART_BACKWALL_CLASS));
if (err) return err;
Eo *prev_obj = edje_object_part_swallow_get(sd->backwall, "efl.content");
@@ -372,15 +661,15 @@ _efl_ui_popup_part_backwall_efl_file_load(Eo *obj, void *_pd EINA_UNUSED)
efl_del(prev_obj);
}
- Eo *image = elm_image_add(pd->obj);
+ Eo *image = efl_add(EFL_UI_IMAGE_CLASS, pd->obj);
Eina_Bool ret;
const Eina_File *f;
f = efl_file_mmap_get(obj);
if (f)
- ret = elm_image_mmap_set(image, f, efl_file_key_get(obj));
+ ret = efl_file_simple_mmap_load(image, f, efl_file_key_get(obj));
else
- ret = elm_image_file_set(image, efl_file_get(obj), efl_file_key_get(obj));
+ ret = efl_file_simple_load(image, efl_file_get(obj), efl_file_key_get(obj));
if (!ret)
{
efl_del(image);
@@ -396,9 +685,4 @@ _efl_ui_popup_part_backwall_efl_file_load(Eo *obj, void *_pd EINA_UNUSED)
/* Efl.Part end */
-/* Internal EO APIs and hidden overrides */
-
-#define EFL_UI_POPUP_EXTRA_OPS \
- ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_popup)
-
#include "efl_ui_popup.eo.c"
diff --git a/src/lib/elementary/efl_ui_popup.eo b/src/lib/elementary/efl_ui_popup.eo
index 4fc5548e6b..15dde23413 100644
--- a/src/lib/elementary/efl_ui_popup.eo
+++ b/src/lib/elementary/efl_ui_popup.eo
@@ -36,15 +36,34 @@ class @beta Efl.Ui.Popup extends Efl.Ui.Layout_Base implements Efl.Content, Efl.
time: double; [[Timeout in seconds]]
}
}
- @property popup_size {
+ @property anchor {
set {
- [[Set the popup size.]]
+ [[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 {
- [[get the current popup size.]]
+ [[Returns the anchor object which the popup is following.]]
}
values {
- size: Eina.Size2D;
+ 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]]
}
}
}
diff --git a/src/lib/elementary/efl_ui_popup_part_backwall.eo b/src/lib/elementary/efl_ui_popup_part_backwall.eo
index 4a6a914a45..8b4eea33bf 100644
--- a/src/lib/elementary/efl_ui_popup_part_backwall.eo
+++ b/src/lib/elementary/efl_ui_popup_part_backwall.eo
@@ -25,6 +25,9 @@ class @beta Efl.Ui.Popup_Part_Backwall extends Efl.Ui.Layout_Part implements Efl
}
}
implements {
+ Efl.File.file { get; }
+ Efl.File.key { get; }
Efl.File.load;
+ Efl.File.unload;
}
}
diff --git a/src/lib/elementary/efl_ui_popup_private.h b/src/lib/elementary/efl_ui_popup_private.h
index 3cf0eee24a..d29c4b24c1 100644
--- a/src/lib/elementary/efl_ui_popup_private.h
+++ b/src/lib/elementary/efl_ui_popup_private.h
@@ -7,11 +7,12 @@ 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 needs_group_calc : 1;
- Eina_Bool needs_size_calc : 1;
- Eina_Bool needs_align_calc : 1;
+ Eina_Bool in_calc : 1;
};
#define EFL_UI_POPUP_DATA_GET_OR_RETURN(o, ptr, ...) \
diff --git a/src/lib/elementary/efl_ui_position_manager_common.h b/src/lib/elementary/efl_ui_position_manager_common.h
new file mode 100644
index 0000000000..0c6a847bae
--- /dev/null
+++ b/src/lib/elementary/efl_ui_position_manager_common.h
@@ -0,0 +1,80 @@
+#ifndef EFL_UI_POSITION_MANAGER_COMMON_H
+#define EFL_UI_POSITION_MANAGER_COMMON_H 1
+
+#include <Eina.h>
+#include <Efl_Ui.h>
+#include "efl_ui_position_manager_entity.eo.h"
+
+typedef struct {
+ void *data;
+ Efl_Ui_Position_Manager_Batch_Access_Entity access; //this can also be the size accessor, but that does not matter here
+ Eina_Free_Cb free_cb;
+} Api_Callback;
+
+typedef struct {
+ unsigned int start_id, end_id;
+} Vis_Segment;
+
+static inline int
+_fill_buffer(Api_Callback *cb , int start_id, int len, int *group_id, void *data)
+{
+ Efl_Ui_Position_Manager_Batch_Result res;
+ Eina_Rw_Slice slice;
+ slice.mem = data;
+ slice.len = len;
+
+ res = cb->access(cb->data, start_id, slice);
+
+ if (group_id)
+ *group_id = res.group_id;
+
+ return res.filled_items;
+}
+
+static inline void
+vis_change_segment(Api_Callback *cb, int a, int b, Eina_Bool flag)
+{
+ const int len = 50;
+ Efl_Ui_Position_Manager_Batch_Entity_Access data[len];
+
+ if (a == b) return;
+
+ for (int i = MIN(a, b); i < MAX(a, b); ++i)
+ {
+ Efl_Gfx_Entity *ent = NULL;
+ int buffer_id = (i-MIN(a,b)) % len;
+
+ if (buffer_id == 0)
+ {
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(cb, MIN(a,b), len, NULL, data) >= 0);
+ }
+ ent = data[buffer_id].entity;
+ if (ent && !flag && (efl_ui_focus_object_focus_get(ent) || efl_ui_focus_object_child_focus_get(ent)))
+ {
+ //we should not make focused object invisible, rather move it to some parking lot
+ efl_gfx_entity_position_set(ent, EINA_POSITION2D(-9999,-9999));
+ }
+ if (ent && !efl_ui_focus_object_focus_get(ent))
+ {
+ efl_gfx_entity_visible_set(ent, flag);
+ }
+ }
+}
+#endif
+
+static inline void
+vis_segment_swap(Api_Callback *cb, Vis_Segment new, Vis_Segment old)
+{
+ if (new.end_id <= old.start_id || new.start_id >= old.end_id)
+ {
+ //it is important to first make the segment visible here, and then hide the rest
+ //otherwise we get a state where item_container has 0 subchildren, which triggers a lot of focus logic.
+ vis_change_segment(cb, new.start_id, new.end_id, EINA_TRUE);
+ vis_change_segment(cb, old.start_id, old.end_id, EINA_FALSE);
+ }
+ else
+ {
+ vis_change_segment(cb, old.start_id, new.start_id, (old.start_id > new.start_id));
+ vis_change_segment(cb, old.end_id, new.end_id, (old.end_id < new.end_id));
+ }
+}
diff --git a/src/lib/elementary/efl_ui_position_manager_entity.c b/src/lib/elementary/efl_ui_position_manager_entity.c
new file mode 100644
index 0000000000..110f88457a
--- /dev/null
+++ b/src/lib/elementary/efl_ui_position_manager_entity.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include "elementary_config.h"
+#endif
+
+#define ELM_LAYOUT_PROTECTED
+#define EFL_UI_SCROLL_MANAGER_PROTECTED
+#define EFL_UI_SCROLLBAR_PROTECTED
+
+#include <Efl_Ui.h>
+#include "elm_priv.h"
+
+#define MY_CLASS EFL_UI_POSITION_MANAGER_ENTITY_CLASS
+
+#include "efl_ui_position_manager_entity.eo.c"
diff --git a/src/lib/elementary/efl_ui_position_manager_entity.eo b/src/lib/elementary/efl_ui_position_manager_entity.eo
new file mode 100644
index 0000000000..4e58a6ce1c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_position_manager_entity.eo
@@ -0,0 +1,158 @@
+import efl_ui;
+
+enum Efl.Ui.Position_Manager.Batch_Group_State{
+ [[Enum expressing the group related state of a item.]]
+ no_group = 0, [[This item is not a group item and is not part of any group.]]
+ group = 1, [[This item is a group item.]]
+ part_of_group = 2 [[This item is part of a group.]]
+}
+
+struct Efl.Ui.Position_Manager.Batch_Entity_Access{
+ [[Struct that is getting filled by the object function callback.]]
+ entity : Efl.Gfx.Entity; [[The canvas object.]]
+ group : Efl.Ui.Position_Manager.Batch_Group_State; [[If this is a group item.]]
+}
+
+struct Efl.Ui.Position_Manager.Batch_Size_Access{
+ [[Struct that is getting filled by the size function callback.]]
+ size : Eina.Size2D; [[The size of the element.]]
+ group : Efl.Ui.Position_Manager.Batch_Group_State; [[If this is a group item.]]
+}
+
+struct Efl.Ui.Position_Manager.Batch_Result {
+ [[Struct that is returned by the function callbacks.]]
+ group_id : int; [[The group of the first item. If the first item is a group, or the first item does not have a group, -1 will be the id]]
+ filled_items : int; [[The number of items that are filled into the slice]]
+}
+
+function Efl.Ui.Position_Manager.Batch_Access_Entity {
+ [[ Function callback for getting a batch of items.]]
+ params {
+ start_id : int; [[The id of the first item to fetch]]
+ memory : rw_slice<Efl.Ui.Position_Manager.Batch_Entity_Access>; [[The slice to fill the information in, the full slice will be filled if there are enough items]]
+ }
+ return: Efl.Ui.Position_Manager.Batch_Result; [[The returned stats of this function call.]]
+};
+
+
+function Efl.Ui.Position_Manager.Batch_Access_Size {
+ [[ Function callback for getting sizes of a batch of items]]
+ params {
+ start_id : int; [[The id of the first item to fetch]]
+ memory : rw_slice<Efl.Ui.Position_Manager.Batch_Size_Access>; [[The slice to fill the information in, the full slice will be filled if there are enough items]]
+ }
+ return: Efl.Ui.Position_Manager.Batch_Result; [[The returned stats of this function call]]
+};
+
+struct Efl.Ui.Position_Manager.Range_Update {
+ [[A struct containing the the updated range of visible items in this position manger.]]
+ start_id : uint; [[The first item that is visible]]
+ end_id : uint; [[The last item that is visible]]
+}
+
+interface @beta Efl.Ui.Position_Manager.Entity extends Efl.Ui.Layout_Orientable
+{
+ [[
+ This abstracts the basic placement of items in a not defined form under a viewport.
+
+ The interface gets a defined set of elements that is meant to be displayed. The implementation provides a way to calculate the size that is required to display all items. Every time this absolut size of items is changed, content_size,changed is called.
+ ]]
+ methods {
+ @property data_access {
+ [[This gives access to items to be managed. The manager reads this information and modifies the retrieved items' positions and sizes.
+
+ $obj_access gives access to the graphical entitites to manage. Some of them might be NULL, meaning they are not yet ready to be displayed. Their size in the $size_access array will be correct, though, so other entities can still be positioned correctly.
+ Typically, only entities inside the viewport will be retrieved.
+
+ $size_access gives access to the 2D sizes for the items to manage. All sizes will always be valid, and might change over time (indicated through the @.item_size_changed method).
+ The whole range might need to be traversed in order to calculate the position of all items in some arrangements.
+
+ You can access a batch of objects or sizes by calling the here passed function callbacks. Further details can be found at the function definitions.
+ ]]
+ set {
+
+ }
+ values {
+ obj_access : Efl.Ui.Position_Manager.Batch_Access_Entity; [[Function callback for canvas objects, even if the start_id is valid, the returned objects may be NULL]]
+ size_access : Efl.Ui.Position_Manager.Batch_Access_Size; [[Function callback for the size, returned values are always valid, but might be changed / updated]]
+ size : int; [[valid size for start_id, 0 <= i < size]]
+ }
+ }
+ @property viewport {
+ [[This is the position and size of the viewport, where elements are displayed in.
+ Entities outside this viewport will not be shown.]]
+ set {
+
+ }
+ values {
+ viewport : Eina.Rect;
+ }
+ }
+ @property scroll_position {
+ [[Move the items relative to the viewport.
+
+ The items that are managed with this position manager might be bigger than the actual viewport.
+ The positioning of the layer where all items are on is described by these values.
+ 0.0,0.0 means that layer is moved that the top left items are shown,
+ 1.0,1.0 means, that the lower right items are shown.
+ ]]
+ set {
+
+ }
+ values {
+ x : double; [[X position of the scroller, valid form 0 to 1.0]]
+ y : double; [[Y position of the scroller, valid form 0 to 1.0]]
+ }
+ }
+ position_single_item {
+ [[Return the position and size of item idx
+
+ This method returns the size and position of the item at $idx.
+ Even if the item is outside the viewport, the returned rectangle must be valid. The result can be used for scrolling calculations.
+ ]]
+ params {
+ idx : int; [[The id for the item]]
+ }
+ return : Eina.Rect; [[Position and Size in canvas coordinations]]
+ }
+ item_added {
+ [[The new item $subobj has been added at the $added_index field.
+
+ The accessor provided through @.data_access will contain updated Entities.]]
+ params {
+ added_index : int;
+ subobj : Efl.Gfx.Entity;
+ }
+ }
+ item_removed {
+ [[The item $subobj previously at position $removed_index has been removed.
+ The accessor provided through @.data_access will contain updated Entities.
+ ]]
+ params {
+ removed_index : int;
+ subobj : Efl.Gfx.Entity;
+ }
+ }
+ item_size_changed {
+ [[The size of the items from $start_id to $end_id have been changed.
+ The positioning and sizing of all items will be updated]]
+ params {
+ start_id : int; [[The first item that has a new size]]
+ end_id : int; [[The last item that has a new size]]
+ }
+ }
+ relative_item {
+ [[translate the current_id, into a new id which is oriented in the $direction of $current_id. In case that there is no item, -1 is returned]]
+ params {
+ current_id : uint; [[The id where the direction is oriented at]]
+ direction : Efl.Ui.Focus.Direction; [[The direction where the new id is]]
+ }
+ return : int; [[The id of the item in that direction, or -1 if there is no item in that direction]]
+ }
+ }
+ events {
+ content_size,changed : Eina.Size2D; [[Emitted when the aggregate size of all items has changed. This can be used to resize an enclosing Pan object.]]
+ content_min_size,changed : Eina.Size2D; [[Emitted when the minimum size of all items has changed. The minimum size is the size, that this position_manager needs at *least* to display a single item.]]
+ visible_range,changed : Efl.Ui.Position_Manager.Range_Update;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_position_manager_grid.c b/src/lib/elementary/efl_ui_position_manager_grid.c
new file mode 100644
index 0000000000..3968884442
--- /dev/null
+++ b/src/lib/elementary/efl_ui_position_manager_grid.c
@@ -0,0 +1,764 @@
+#ifdef HAVE_CONFIG_H
+#include "elementary_config.h"
+#endif
+
+#include <Efl_Ui.h>
+#include <Elementary.h>
+#include "elm_widget.h"
+#include "elm_priv.h"
+#include "efl_ui_position_manager_common.h"
+
+#define MY_CLASS EFL_UI_POSITION_MANAGER_GRID_CLASS
+#define MY_DATA_GET(obj, pd) \
+ Efl_Ui_Position_Manager_Grid_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+
+typedef struct {
+ Api_Callback min_size, object;
+ unsigned int size;
+ unsigned int groups;
+ Eina_Rect viewport;
+ Eina_Vector2 scroll_position;
+ Efl_Ui_Layout_Orientation dir;
+ Vis_Segment prev_run;
+ Eina_Size2D max_min_size;
+ Eina_Size2D last_viewport_size;
+ Eina_Size2D prev_min_size;
+
+ Eina_Inarray *group_cache;
+ Eina_Bool group_cache_dirty;
+ int *size_cache;
+ Eina_Bool size_cache_dirty;
+ Eo *last_group;
+ Eina_Future *rebuild_absolut_size;
+} Efl_Ui_Position_Manager_Grid_Data;
+
+typedef struct {
+ Eina_Bool real_group;
+ Eina_Size2D group_header_size;
+ int items;
+} Group_Cache_Line;
+
+static void
+_group_cache_require(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ unsigned int i;
+ const int len = 100;
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[len];
+ Group_Cache_Line line = { 0 };
+
+ if (!pd->group_cache_dirty)
+ return;
+
+ pd->group_cache_dirty = EINA_FALSE;
+ if (pd->group_cache)
+ eina_inarray_free(pd->group_cache);
+ pd->group_cache = eina_inarray_new(sizeof(Group_Cache_Line), 10);
+
+ for (i = 0; i < pd->size; ++i)
+ {
+ int buffer_id = i % len;
+
+ if (buffer_id == 0)
+ {
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, len, NULL, size_buffer) > 0);
+ }
+
+ if (size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
+ {
+ eina_inarray_push(pd->group_cache, &line);
+ line.real_group = EINA_TRUE;
+ line.group_header_size = size_buffer[buffer_id].size;
+ line.items = 1;
+ }
+ else if (size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_PART_OF_GROUP ||
+ (!line.real_group && size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP))
+ {
+ line.items ++;
+ }
+ else if (size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP && line.real_group)
+ {
+ eina_inarray_push(pd->group_cache, &line);
+ line.real_group = EINA_FALSE;
+ line.group_header_size = EINA_SIZE2D(0, 0);
+ line.items = 0;
+ }
+ }
+ eina_inarray_push(pd->group_cache, &line);
+}
+
+static inline void
+_group_cache_invalidate(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ pd->group_cache_dirty = EINA_TRUE;
+ pd->size_cache_dirty = EINA_TRUE;
+}
+
+static void
+_size_cache_require(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ if (!pd->size_cache_dirty) return;
+
+ _group_cache_require(obj, pd);
+
+ pd->size_cache_dirty = EINA_FALSE;
+ if (pd->size_cache)
+ free(pd->size_cache);
+ pd->size_cache = calloc(sizeof(int), eina_inarray_count(pd->group_cache));
+
+ for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
+ {
+ Group_Cache_Line *line = eina_inarray_nth(pd->group_cache, i);
+ int header_out = 0;
+ if (line->real_group)
+ header_out = 1;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ pd->size_cache[i] = line->group_header_size.h +
+ (ceil(
+ (double)(line->items - header_out)/ /* the number of real items in the group (- the group item) */
+ (int)(pd->viewport.w/pd->max_min_size.w))) /* devided by the number of items per row */
+ *pd->max_min_size.h;
+ else
+ pd->size_cache[i] = (ceil((double)(line->items - header_out)/
+ (int)((pd->viewport.h-line->group_header_size.h)/pd->max_min_size.h)))*pd->max_min_size.w;
+ }
+}
+
+static inline void
+_size_cache_invalidate(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ pd->size_cache_dirty = EINA_TRUE;
+}
+
+typedef struct {
+ int resulting_id;
+ int consumed_space;
+} Search_Result;
+
+static inline Search_Result
+_search_id(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int relevant_space_size)
+{
+ int consumed_space = 0;
+ int consumed_groups = -1;
+ int consumed_ids = 0;
+ int sub_ids = 0;
+ Search_Result res;
+
+ //first we search how many blocks we can skip
+ for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
+ {
+ Group_Cache_Line *line = eina_inarray_nth(pd->group_cache, i);
+ if (consumed_space + pd->size_cache[i] > relevant_space_size)
+ break;
+ consumed_space += pd->size_cache[i];
+ consumed_groups = i;
+ consumed_ids += line->items;
+ }
+ Group_Cache_Line *line = NULL;
+ if (consumed_groups > -1 && consumed_groups + 1 < (int)eina_inarray_count(pd->group_cache))
+ line = eina_inarray_nth(pd->group_cache, consumed_groups + 1);
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ //now we have relevant_space_size - consumed_space left maybe we are searching the group item
+
+ if (line && line->real_group)
+ {
+ if (consumed_space + line->group_header_size.h > relevant_space_size)
+ {
+ res.resulting_id = consumed_ids;
+ res.consumed_space = consumed_space;
+ return res;
+ }
+ else
+ {
+ consumed_space += line->group_header_size.h;
+ consumed_ids += 1;
+ }
+ }
+ //now we need to locate at which id we are starting
+ int space_top = relevant_space_size - consumed_space;
+ consumed_space += floor(space_top/pd->max_min_size.h)*pd->max_min_size.h;
+ sub_ids = floor(space_top/pd->max_min_size.h)*(pd->viewport.w/pd->max_min_size.w);
+ }
+ else
+ {
+ int header_height = 0;
+ if (line && line->real_group)
+ {
+ header_height = line->group_header_size.h;
+ }
+ //now we need to locate at which id we are starting
+ const int space_left = relevant_space_size - consumed_space;
+ consumed_space += floor(space_left/pd->max_min_size.w)*pd->max_min_size.w;
+ sub_ids = floor(space_left/pd->max_min_size.w)*((pd->viewport.h-header_height)/pd->max_min_size.h);
+ if (line && line->real_group &&
+ sub_ids > 0) /* if we are in the first row, we need the group item to be visible, otherwise, we need to add that to the consumed ids */
+ {
+ sub_ids += 1;
+ }
+ }
+ res.resulting_id = consumed_ids + sub_ids;
+ res.consumed_space = consumed_space;
+ return res;
+}
+
+static inline Eina_Bool
+_search_start_end(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int relevant_viewport, int relevant_space_size, unsigned int step, Vis_Segment *cur, int *consumed_space)
+{
+ Search_Result start = _search_id(obj, pd, MAX(relevant_space_size, 0));
+ Search_Result end = _search_id(obj, pd, MAX(relevant_space_size, 0)+relevant_viewport+step*2);
+ cur->start_id = MIN(MAX(start.resulting_id, 0), (int)pd->size);
+ cur->end_id = MAX(MIN(end.resulting_id, (int)pd->size), 0);
+
+ *consumed_space = start.consumed_space;
+
+ return EINA_TRUE;
+}
+
+typedef struct {
+ int relevant_space_size;
+ int consumed_space;
+ Vis_Segment new;
+ Eo *floating_group;
+ Eina_Size2D floating_size;
+ Eo *placed_item;
+} Item_Position_Context;
+
+
+static inline void
+_place_grid_item(Eina_Rect *geom, Efl_Ui_Position_Manager_Grid_Data *pd, int x, int y)
+{
+ geom->x += x*pd->max_min_size.w;
+ geom->y += y*pd->max_min_size.h;
+ geom->size = pd->max_min_size;
+}
+
+static inline void
+_position_items_vertical(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Item_Position_Context *ctx)
+{
+ Eina_Position2D start = pd->viewport.pos;
+ unsigned int i;
+ const int len = 100;
+ int columns, last_block_start = ctx->new.start_id;
+ Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
+
+ if (!pd->viewport.w || !pd->viewport.h) return;
+
+ start.y -= (ctx->relevant_space_size - ctx->consumed_space);
+ columns = pd->viewport.w/pd->max_min_size.w;
+
+ for (i = ctx->new.start_id; i < ctx->new.end_id; ++i)
+ {
+ int buffer_id = (i-ctx->new.start_id) % len;
+ if (buffer_id == 0)
+ {
+ int tmp_group;
+
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, i, len, &tmp_group, obj_buffer) > 0);
+ if (tmp_group != -1 && i == ctx->new.start_id)
+ {
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
+ Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[1];
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, tmp_group, 1, NULL, size_buffer) != 0);
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, tmp_group, 1, NULL, obj_buffer) != 0);
+ ctx->floating_group = obj_buffer[0].entity;
+ ctx->floating_size.h = size_buffer[0].size.h;
+ ctx->floating_size.w = pd->viewport.w;
+ }
+ }
+ Eina_Rect geom;
+ geom.pos = start;
+ int x = (i - last_block_start)%columns;
+ int y = (i - last_block_start)/columns;
+
+ if (obj_buffer[buffer_id].entity == pd->last_group)
+ pd->last_group = NULL;
+
+ if (obj_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
+ {
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, 1, NULL, size_buffer) == 1);
+
+ if (x != 0)
+ y += 1;
+
+ last_block_start = i + 1;
+ start.y += size_buffer[0].size.h + y*pd->max_min_size.h;
+
+ geom.size = pd->viewport.size;
+ geom.h = size_buffer[0].size.h;
+ geom.y += y*pd->max_min_size.h;
+ if (!ctx->placed_item)
+ ctx->placed_item = obj_buffer[buffer_id].entity;
+ }
+ else
+ {
+ _place_grid_item(&geom, pd, x, y);
+ }
+
+ efl_gfx_entity_geometry_set(obj_buffer[buffer_id].entity, geom);
+ }
+}
+
+static inline void
+_position_items_horizontal(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Item_Position_Context *ctx)
+{
+ Eina_Position2D start = pd->viewport.pos;
+ unsigned int i;
+ const int len = 100;
+ int columns, last_block_start = ctx->new.start_id;
+ Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
+
+ if (!pd->viewport.w || !pd->viewport.h) return;
+
+ start.x -= (ctx->relevant_space_size - ctx->consumed_space);
+ columns = (pd->viewport.h)/pd->max_min_size.h;
+
+ for (i = ctx->new.start_id; i < ctx->new.end_id; ++i)
+ {
+ int buffer_id = (i-ctx->new.start_id) % len;
+ if (buffer_id == 0)
+ {
+ int tmp_group;
+
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, i, len, &tmp_group, obj_buffer) > 0);
+ if (tmp_group != -1 && i == ctx->new.start_id && pd->dir != EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
+ Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[1];
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, tmp_group, 1, NULL, size_buffer) != 0);
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, tmp_group, 1, NULL, obj_buffer) != 0);
+ start.y += size_buffer[0].size.h;
+ columns = (pd->viewport.h - size_buffer[0].size.h)/pd->max_min_size.h;
+ ctx->floating_group = obj_buffer[0].entity;
+ ctx->floating_size.h = size_buffer[0].size.h;
+ ctx->floating_size.w = pd->viewport.w;
+ }
+ }
+ Eina_Rect geom;
+ geom.pos = start;
+
+ int x = (i - last_block_start)/columns;
+ int y = (i - last_block_start)%columns;
+
+ if (obj_buffer[buffer_id].entity == pd->last_group)
+ pd->last_group = NULL;
+
+ if (obj_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
+ {
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, 1, NULL, size_buffer) == 1);
+
+ last_block_start = i + 1;
+ start.y = pd->viewport.y + size_buffer[0].size.h;
+ start.x += x*pd->max_min_size.w;
+
+ geom.size.h = size_buffer[0].size.h;
+ geom.size.w = pd->viewport.w;
+ geom.x += x*pd->max_min_size.w;
+ geom.y = pd->viewport.y;
+
+ columns = (pd->viewport.h - size_buffer[0].size.h)/pd->max_min_size.h;
+ if (!ctx->placed_item)
+ ctx->placed_item = obj_buffer[buffer_id].entity;
+ }
+ else
+ {
+ _place_grid_item(&geom, pd, x, y);
+ }
+ efl_gfx_entity_geometry_set(obj_buffer[buffer_id].entity, geom);
+ }
+}
+
+static inline void
+_position_group_items(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Item_Position_Context *ctx)
+{
+ //floating group is not yet positioned, in case it is there, we need to position it there
+ Eina_Rect geom;
+
+ if (!ctx->floating_group && pd->last_group)
+ {
+ efl_gfx_entity_visible_set(pd->last_group, EINA_FALSE);
+ pd->last_group = NULL;
+ }
+
+ if (ctx->floating_group)
+ {
+ geom.pos = pd->viewport.pos;
+ geom.size = ctx->floating_size;
+
+ if (ctx->placed_item)
+ {
+ Eina_Rect placed = efl_gfx_entity_geometry_get(ctx->placed_item);
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ geom.y = MIN(geom.y, placed.y-geom.h);
+ }
+ else
+ {
+ geom.x = MIN(geom.x, placed.x-geom.w);
+ }
+ }
+
+ if (pd->last_group != ctx->floating_group)
+ {
+ efl_gfx_entity_visible_set(pd->last_group, EINA_FALSE);
+ pd->last_group = ctx->floating_group;
+ }
+
+ efl_gfx_entity_visible_set(ctx->floating_group, EINA_TRUE);
+ efl_gfx_stack_raise_to_top(ctx->floating_group);
+ efl_gfx_entity_geometry_set(ctx->floating_group, geom);
+ }
+ else if (ctx->placed_item)
+ {
+ Eina_Rect placed = efl_gfx_entity_geometry_get(ctx->placed_item);
+
+ placed.x = MAX(placed.x, pd->viewport.x);
+ placed.y = MAX(placed.y, pd->viewport.y);
+ efl_gfx_entity_geometry_set(ctx->placed_item, placed);
+ efl_gfx_stack_raise_to_top(ctx->placed_item);
+ }
+}
+
+static void
+_reposition_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ Eina_Size2D space_size;
+ int relevant_space_size, relevant_viewport, consumed_space;
+ Vis_Segment cur;
+ unsigned int step;
+ Efl_Ui_Position_Manager_Range_Update ev;
+ Item_Position_Context ctx;
+
+ if (!pd->size) return;
+ if (pd->max_min_size.w <= 0 || pd->max_min_size.h <= 0) return;
+ if (!eina_inarray_count(pd->group_cache)) return;
+
+ //space size contains the amount of space that is outside the viewport (either to the top or to the left)
+ space_size.w = (MAX(pd->last_viewport_size.w - pd->viewport.w, 0))*pd->scroll_position.x;
+ space_size.h = (MAX(pd->last_viewport_size.h - pd->viewport.h, 0))*pd->scroll_position.y;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ relevant_space_size = space_size.h;
+ relevant_viewport = pd->viewport.h;
+ step = pd->max_min_size.h;
+ }
+ else
+ {
+ relevant_space_size = space_size.w;
+ relevant_viewport = pd->viewport.w;
+ step = pd->max_min_size.w;
+ }
+ if (!_search_start_end(obj, pd, relevant_viewport, relevant_space_size, step, &cur, &consumed_space))
+ return;
+
+ //to performance optimize the whole widget, we are setting the objects that are outside the viewport to visibility false
+ //The code below ensures that things outside the viewport are always hidden, and things inside the viewport are visible
+ vis_segment_swap(&pd->object, cur, pd->prev_run);
+
+ ctx.new = cur;
+ ctx.consumed_space = consumed_space;
+ ctx.relevant_space_size = relevant_space_size;
+ ctx.floating_group = NULL;
+ ctx.placed_item = NULL;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ _position_items_vertical(obj, pd, &ctx);
+ _position_group_items(obj, pd, &ctx);
+ }
+ else
+ {
+ _position_items_horizontal(obj, pd, &ctx);
+ _position_group_items(obj, pd, &ctx);
+ }
+
+ if (pd->prev_run.start_id != cur.start_id || pd->prev_run.end_id != cur.end_id)
+ {
+ ev.start_id = pd->prev_run.start_id = cur.start_id;
+ ev.end_id = pd->prev_run.end_id = cur.end_id;
+ efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_VISIBLE_RANGE_CHANGED, &ev);
+ }
+}
+
+static inline void
+_flush_abs_size(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ Eina_Size2D vp_size;
+ int sum_of_cache = 0;
+
+ if (!pd->size) return;
+ if (pd->max_min_size.w <= 0 || pd->max_min_size.h <= 0) return;
+
+ _size_cache_require(obj, pd);
+ for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
+ {
+ sum_of_cache += pd->size_cache[i];
+ }
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ vp_size.w = pd->viewport.w;
+ vp_size.h = sum_of_cache;
+ }
+ else
+ {
+ vp_size.h = pd->viewport.h;
+ vp_size.w = sum_of_cache;
+ }
+ if (vp_size.h != pd->last_viewport_size.h || vp_size.w != pd->last_viewport_size.w)
+ {
+ pd->last_viewport_size = vp_size;
+ efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_SIZE_CHANGED, &vp_size);
+ }
+}
+
+static inline void
+_update_min_size(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int added_index EINA_UNUSED, Eina_Size2D min_size)
+{
+ pd->max_min_size.w = MAX(pd->max_min_size.w, min_size.w);
+ pd->max_min_size.h = MAX(pd->max_min_size.h, min_size.h);
+}
+
+static inline void
+_flush_min_size(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ Eina_Size2D min_size = pd->max_min_size;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ min_size.h = -1;
+ else
+ min_size.w = -1;
+
+ if (pd->prev_min_size.w != min_size.w || pd->prev_min_size.h != min_size.h)
+ {
+ pd->prev_min_size = min_size;
+ efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, &min_size);
+ }
+}
+
+EOLIAN static void
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_data_access_set(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, void *obj_access_data, Efl_Ui_Position_Manager_Batch_Access_Entity obj_access, Eina_Free_Cb obj_access_free_cb, void *size_access_data, Efl_Ui_Position_Manager_Batch_Access_Size size_access, Eina_Free_Cb size_access_free_cb, int size)
+{
+ pd->object.data = obj_access_data;
+ pd->object.access = obj_access;
+ pd->object.free_cb = obj_access_free_cb;
+ pd->min_size.data = size_access_data;
+ pd->min_size.access = size_access;
+ pd->min_size.free_cb = size_access_free_cb;
+ pd->size = size;
+}
+
+EOLIAN static void
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_viewport_set(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Eina_Rect viewport)
+{
+ _size_cache_invalidate(obj, pd);
+ pd->viewport = viewport;
+ _flush_abs_size(obj, pd);
+ _reposition_content(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_scroll_position_set(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, double x, double y)
+{
+ pd->scroll_position.x = x;
+ pd->scroll_position.y = y;
+ _reposition_content(obj, pd);
+}
+
+static Eina_Value
+_rebuild_job_cb(void *data, Eina_Value v EINA_UNUSED, const Eina_Future *f EINA_UNUSED)
+{
+ MY_DATA_GET(data, pd);
+
+ if (!efl_alive_get(data)) return EINA_VALUE_EMPTY;
+
+ _flush_abs_size(data, pd);
+ _reposition_content(data, pd);
+ pd->rebuild_absolut_size = NULL;
+
+ return EINA_VALUE_EMPTY;
+}
+
+static void
+_schedule_recalc_abs_size(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ if (pd->rebuild_absolut_size) return;
+
+ pd->rebuild_absolut_size = efl_loop_job(efl_app_main_get());
+ eina_future_then(pd->rebuild_absolut_size, _rebuild_job_cb, obj);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_item_added(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd, int added_index, Efl_Gfx_Entity *subobj EINA_UNUSED)
+{
+ Efl_Ui_Position_Manager_Batch_Size_Access size[1];
+ pd->size ++;
+
+ efl_gfx_entity_visible_set(subobj, EINA_FALSE);
+ _group_cache_invalidate(obj, pd);
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, added_index, 1, NULL, &size) == 1);
+ _update_min_size(obj, pd, added_index, size[0].size);
+ _flush_min_size(obj, pd);
+ _schedule_recalc_abs_size(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_item_removed(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int removed_index EINA_UNUSED, Efl_Gfx_Entity *subobj EINA_UNUSED)
+{
+ //we ignore here that we might loose the item giving the current max min size
+ EINA_SAFETY_ON_FALSE_RETURN(pd->size > 0);
+ pd->size --;
+ _group_cache_invalidate(obj, pd);
+ pd->prev_run.start_id = MIN(pd->prev_run.start_id, pd->size);
+ pd->prev_run.end_id = MIN(pd->prev_run.end_id, pd->size);
+ _schedule_recalc_abs_size(obj, pd);
+ efl_gfx_entity_visible_set(subobj, EINA_TRUE);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_item_size_changed(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd, int start_id, int end_id)
+{
+ const int len = 50;
+ Efl_Ui_Position_Manager_Batch_Size_Access data[len];
+
+ for (int i = start_id; i <= end_id; ++i)
+ {
+ int buffer_id = (i-start_id) % len;
+ if (buffer_id == 0)
+ {
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, start_id, len, NULL, data) >= 0);
+ }
+ _update_min_size(obj, pd, i, data[i-start_id].size);
+ }
+ _size_cache_invalidate(obj, pd);
+ _flush_min_size(obj, pd);
+ _schedule_recalc_abs_size(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_grid_efl_ui_layout_orientable_orientation_set(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Efl_Ui_Layout_Orientation dir)
+{
+ pd->dir = dir;
+ _flush_min_size(obj, pd);
+ _flush_abs_size(obj, pd);
+ _reposition_content(obj, pd); //FIXME we could check if this is needed or not
+}
+
+
+EOLIAN static Efl_Ui_Layout_Orientation
+_efl_ui_position_manager_grid_efl_ui_layout_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
+{
+ return pd->dir;
+}
+
+EOLIAN static Eina_Rect
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_position_single_item(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int idx)
+{
+ Eina_Rect geom;
+ Eina_Size2D space_size;
+ unsigned int relevant_space_size;
+ unsigned int group_consumed_size = 0;
+ unsigned int group_consumed_ids = 0;
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
+
+ if (!pd->size) return EINA_RECT(0, 0, 0, 0);
+ if (pd->max_min_size.w <= 0 || pd->max_min_size.h <= 0) return EINA_RECT(0, 0, 0, 0);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(_fill_buffer(&pd->min_size, idx, 1, NULL, size_buffer) == 1, EINA_RECT_EMPTY());
+
+ _size_cache_require(obj, pd);
+ _flush_abs_size(obj, pd);
+
+ space_size.w = (MAX(pd->last_viewport_size.w - pd->viewport.w, 0))*pd->scroll_position.x;
+ space_size.h = (MAX(pd->last_viewport_size.h - pd->viewport.h, 0))*pd->scroll_position.y;
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ relevant_space_size = space_size.h;
+ else
+ relevant_space_size = space_size.w;
+
+ geom.size = pd->max_min_size;
+ geom.pos = pd->viewport.pos;
+
+ for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
+ {
+ Group_Cache_Line *line = eina_inarray_nth(pd->group_cache, i);
+ if ((int)group_consumed_ids + line->items > idx)
+ break;
+
+ group_consumed_size += pd->size_cache[i];
+ group_consumed_ids += line->items;
+ if (line->real_group && idx == (int)group_consumed_ids + 1)
+ {
+ geom.y = (relevant_space_size - group_consumed_size);
+ geom.size = size_buffer[0].size;
+
+ return geom;
+ }
+ else if (line->real_group)
+ group_consumed_size += line->group_header_size.h;
+ }
+
+ if (idx > 0)
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(group_consumed_ids < (unsigned int)idx, EINA_RECT(0, 0, 0, 0));
+ else if (idx == 0)
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(group_consumed_ids == 0, EINA_RECT(0, 0, 0, 0));
+
+ int columns = pd->viewport.w/pd->max_min_size.w;
+ int sub_pos_id = idx - group_consumed_ids;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ const int x = (sub_pos_id)%columns;
+ const int y = (sub_pos_id)/columns;
+
+ geom.y -= relevant_space_size;
+ geom.x += pd->max_min_size.w*x;
+ geom.y += group_consumed_size + pd->max_min_size.h*y;
+ }
+ else
+ {
+ const int x = (sub_pos_id)/columns;
+ const int y = (sub_pos_id)%columns;
+
+ geom.x -= relevant_space_size;
+ geom.y += pd->max_min_size.h*y;
+ geom.x += group_consumed_size + pd->max_min_size.w*x;
+ }
+
+ return geom;
+}
+
+EOLIAN static int
+_efl_ui_position_manager_grid_efl_ui_position_manager_entity_relative_item(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, unsigned int current_id, Efl_Ui_Focus_Direction direction)
+{
+ int new_id = current_id;
+ switch(direction)
+ {
+ case EFL_UI_FOCUS_DIRECTION_RIGHT:
+ case EFL_UI_FOCUS_DIRECTION_NEXT:
+ new_id += 1;
+ break;
+ case EFL_UI_FOCUS_DIRECTION_LEFT:
+ case EFL_UI_FOCUS_DIRECTION_PREVIOUS:
+ new_id -= 1;
+ break;
+ case EFL_UI_FOCUS_DIRECTION_UP:
+ //FIXME
+ break;
+ case EFL_UI_FOCUS_DIRECTION_DOWN:
+ //FIXME
+ break;
+ default:
+ new_id = -1;
+ ERR("Uncaught case!");
+ break;
+ }
+ if (new_id < 0 || new_id > (int)pd->size)
+ return -1;
+ else
+ return new_id;
+}
+
+#include "efl_ui_position_manager_grid.eo.c"
diff --git a/src/lib/elementary/efl_ui_position_manager_grid.eo b/src/lib/elementary/efl_ui_position_manager_grid.eo
new file mode 100644
index 0000000000..164b48ff52
--- /dev/null
+++ b/src/lib/elementary/efl_ui_position_manager_grid.eo
@@ -0,0 +1,18 @@
+class @beta Efl.Ui.Position_Manager.Grid extends Efl.Object implements Efl.Ui.Position_Manager.Entity
+{
+ [[Implementation of @Efl.Ui.Position_Manager.Entity for two-dimensional grids.
+
+ Every item in the grid has the same size, which is the biggest minimum size of all items.
+ ]]
+ implements {
+ Efl.Ui.Position_Manager.Entity.data_access {set;}
+ Efl.Ui.Position_Manager.Entity.viewport {set;}
+ Efl.Ui.Position_Manager.Entity.scroll_position {set;}
+ Efl.Ui.Position_Manager.Entity.item_added;
+ Efl.Ui.Position_Manager.Entity.item_removed;
+ Efl.Ui.Position_Manager.Entity.position_single_item;
+ Efl.Ui.Position_Manager.Entity.item_size_changed;
+ Efl.Ui.Position_Manager.Entity.relative_item;
+ Efl.Ui.Layout_Orientable.orientation {set; get;}
+ }
+}
diff --git a/src/lib/elementary/efl_ui_position_manager_list.c b/src/lib/elementary/efl_ui_position_manager_list.c
new file mode 100644
index 0000000000..3200caad8b
--- /dev/null
+++ b/src/lib/elementary/efl_ui_position_manager_list.c
@@ -0,0 +1,513 @@
+#ifdef HAVE_CONFIG_H
+#include "elementary_config.h"
+#endif
+
+
+#include <Efl_Ui.h>
+#include <Elementary.h>
+#include "elm_widget.h"
+#include "elm_priv.h"
+#include "efl_ui_position_manager_common.h"
+
+#define MY_CLASS EFL_UI_POSITION_MANAGER_LIST_CLASS
+#define MY_DATA_GET(obj, pd) \
+ Efl_Ui_Position_Manager_List_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+
+typedef struct {
+ Api_Callback min_size, object;
+ unsigned int size;
+ Eina_Future *rebuild_absolut_size;
+ Eina_Rect viewport;
+ Eina_Size2D abs_size;
+ Eina_Vector2 scroll_position;
+ Efl_Ui_Layout_Orientation dir;
+ int *size_cache;
+ int average_item_size;
+ int maximum_min_size;
+ Vis_Segment prev_run;
+ Efl_Gfx_Entity *last_group;
+} Efl_Ui_Position_Manager_List_Data;
+
+/*
+ * The here used cache is a sum map
+ * Every element in the cache contains the sum of the previous element, and the size of the current item
+ * This is usefull as a lookup of all previous items is O(1).
+ * The tradeoff that makes the cache performant here is, that we only need to walk the whole list of items once in the beginning.
+ * Every other walk of the items is at max the maximum number of items you get into the maximum distance between the average item size and a actaul item size.
+ */
+
+static void
+cache_require(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
+{
+ unsigned int i;
+ const int len = 100;
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[100];
+
+
+ if (pd->size_cache) return;
+
+ if (pd->size == 0)
+ {
+ pd->size_cache = NULL;
+ pd->average_item_size = 0;
+ return;
+ }
+
+ pd->size_cache = calloc(pd->size + 1, sizeof(int));
+ pd->size_cache[0] = 0;
+ pd->maximum_min_size = 0;
+
+ for (i = 0; i < pd->size; ++i)
+ {
+ Eina_Size2D size;
+ int step;
+ int min;
+ int buffer_id = i % len;
+
+ if (buffer_id == 0)
+ {
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, len, NULL, size_buffer) > 0);
+ }
+ size = size_buffer[buffer_id].size;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ step = size.h;
+ min = size.w;
+ }
+ else
+ {
+ step = size.w;
+ min = size.h;
+ }
+ pd->size_cache[i + 1] = pd->size_cache[i] + step;
+ pd->maximum_min_size = MAX(pd->maximum_min_size, min);
+ }
+ pd->average_item_size = pd->size_cache[pd->size]/pd->size;
+}
+
+static void
+cache_invalidate(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
+{
+ if (pd->size_cache)
+ free(pd->size_cache);
+ pd->size_cache = NULL;
+}
+
+static inline int
+cache_access(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, unsigned int idx)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(idx <= pd->size, 0);
+ return pd->size_cache[idx];
+}
+
+static void
+recalc_absolut_size(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd)
+{
+ Eina_Size2D min_size = EINA_SIZE2D(-1, -1);
+ cache_require(obj, pd);
+
+ pd->abs_size = pd->viewport.size;
+
+ if (pd->size)
+ {
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ pd->abs_size.h = MAX(cache_access(obj, pd, pd->size), pd->abs_size.h);
+ else
+ pd->abs_size.w = MAX(cache_access(obj, pd, pd->size), pd->abs_size.w);
+ }
+
+ efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_SIZE_CHANGED, &pd->abs_size);
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ min_size.w = pd->maximum_min_size;
+ }
+ else
+ {
+ min_size.h = pd->maximum_min_size;
+ }
+
+ efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, &min_size);
+}
+
+static inline Vis_Segment
+_search_visual_segment(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd, int relevant_space_size, int relevant_viewport)
+{
+ Vis_Segment cur;
+ //based on the average item size, we jump somewhere into the sum cache.
+ //After beeing in there, we are walking back, until we have less space then viewport size
+ cur.start_id = MIN((unsigned int)(relevant_space_size / pd->average_item_size), pd->size);
+ for (; cache_access(obj, pd, cur.start_id) >= relevant_space_size && cur.start_id > 0; cur.start_id --) { }
+
+ //starting on the start id, we are walking down until the sum of elements is bigger than the lower part of the viewport.
+ cur.end_id = cur.start_id;
+ for (; cur.end_id <= pd->size && cache_access(obj, pd, cur.end_id) <= relevant_space_size + relevant_viewport ; cur.end_id ++) { }
+ cur.end_id = MAX(cur.end_id, cur.start_id + 1);
+ cur.end_id = MIN(cur.end_id, pd->size);
+
+ #ifdef DEBUG
+ printf("space_size %d : starting point : %d : cached_space_starting_point %d end point : %d cache_space_end_point %d\n", space_size.h, cur.start_id, pd->size_cache[cur.start_id], cur.end_id, pd->size_cache[cur.end_id]);
+ #endif
+ if (relevant_space_size > 0)
+ EINA_SAFETY_ON_FALSE_GOTO(cache_access(obj, pd, cur.start_id) <= relevant_space_size, err);
+ if (cur.end_id != pd->size)
+ EINA_SAFETY_ON_FALSE_GOTO(cache_access(obj, pd, cur.end_id) >= relevant_space_size + relevant_viewport, err);
+ EINA_SAFETY_ON_FALSE_GOTO(cur.start_id <= cur.end_id, err);
+
+ return cur;
+
+err:
+ cur.start_id = cur.end_id = 0;
+
+ return cur;
+}
+
+static inline void
+_position_items(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, Vis_Segment new, int relevant_space_size)
+{
+ int group_id = -1;
+ Efl_Gfx_Entity *first_group = NULL, *first_fully_visual_group = NULL;
+ Eina_Size2D first_group_size;
+ Eina_Rect geom;
+ const int len = 100;
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[len];
+ Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
+ unsigned int i;
+
+ //placement of the plain items
+ geom = pd->viewport;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ geom.y -= (relevant_space_size - cache_access(obj, pd, new.start_id));
+ else
+ geom.x -= (relevant_space_size - cache_access(obj, pd, new.start_id));
+
+ for (i = new.start_id; i < new.end_id; ++i)
+ {
+ Eina_Size2D size;
+ Efl_Gfx_Entity *ent = NULL;
+ int buffer_id = (i-new.start_id) % len;
+
+ if (buffer_id == 0)
+ {
+ int tmp_group;
+ int res1, res2;
+
+ res1 = _fill_buffer(&pd->object, i, len, &tmp_group, obj_buffer);
+ res2 = _fill_buffer(&pd->min_size, i, len, NULL, size_buffer);
+ EINA_SAFETY_ON_FALSE_RETURN(res1 == res2);
+ EINA_SAFETY_ON_FALSE_RETURN(res2 > 0);
+
+ if (i == new.start_id)
+ {
+ if (tmp_group > 0)
+ group_id = tmp_group;
+ else if (obj_buffer[0].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
+ group_id = i;
+ }
+ }
+
+ size = size_buffer[buffer_id].size;
+ ent = obj_buffer[buffer_id].entity;
+
+ if (ent == pd->last_group)
+ {
+ pd->last_group = NULL;
+ }
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ geom.h = size.h;
+ else
+ geom.w = size.w;
+
+ if (!first_fully_visual_group && obj_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP &&
+ eina_spans_intersect(geom.x, geom.w, pd->viewport.x, pd->viewport.w) &&
+ eina_spans_intersect(geom.y, geom.h, pd->viewport.y, pd->viewport.h))
+ {
+ first_fully_visual_group = obj_buffer[buffer_id].entity;
+ }
+
+ if (ent)
+ efl_gfx_entity_geometry_set(ent, geom);
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ geom.y += size.h;
+ else
+ geom.x += size.w;
+ }
+ //Now place group items
+
+ if (group_id > 0)
+ {
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, group_id, 1, NULL, obj_buffer) == 1);
+ EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, group_id, 1, NULL, size_buffer) == 1);
+ first_group = obj_buffer[0].entity;
+ first_group_size = size_buffer[0].size;
+ }
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ first_group_size.w = pd->viewport.w;
+ else
+ first_group_size.h = pd->viewport.h;
+
+ //if there is a new group item, display the new one, and hide the old one
+ if (first_group != pd->last_group)
+ {
+ efl_gfx_entity_visible_set(pd->last_group, EINA_FALSE);
+ efl_gfx_stack_raise_to_top(first_group);
+ pd->last_group = first_group;
+ }
+ //we have to set the visibility again here, as changing the visual segments might overwrite our visibility state
+ efl_gfx_entity_visible_set(first_group, EINA_TRUE);
+
+ //in case there is another group item coming in, the new group item (which is placed as normal item) moves the group item to the top
+ Eina_Position2D first_group_pos = EINA_POSITION2D(pd->viewport.x, pd->viewport.y);
+ if (first_fully_visual_group && first_fully_visual_group != first_group)
+ {
+ Eina_Position2D first_visual_group;
+ first_visual_group = efl_gfx_entity_position_get(first_fully_visual_group);
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ first_group_pos.y = MIN(first_group_pos.y, first_visual_group.y - first_group_size.h);
+ else
+ first_group_pos.x = MIN(first_group_pos.x, first_visual_group.x - first_group_size.w);
+ }
+
+ efl_gfx_entity_position_set(first_group, first_group_pos);
+ efl_gfx_entity_size_set(first_group, first_group_size);
+}
+
+
+static void
+position_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
+{
+ Eina_Size2D space_size;
+ Vis_Segment cur;
+ int relevant_space_size, relevant_viewport;
+ Efl_Ui_Position_Manager_Range_Update ev;
+
+ if (!pd->size) return;
+ if (pd->average_item_size <= 0) return;
+
+ //space size contains the amount of space that is outside the viewport (either to the top or to the left)
+ space_size.w = (MAX(pd->abs_size.w - pd->viewport.w, 0))*pd->scroll_position.x;
+ space_size.h = (MAX(pd->abs_size.h - pd->viewport.h, 0))*pd->scroll_position.y;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ relevant_space_size = space_size.h;
+ relevant_viewport = pd->viewport.h;
+ }
+ else
+ {
+ relevant_space_size = space_size.w;
+ relevant_viewport = pd->viewport.w;
+ }
+
+ cur = _search_visual_segment(obj, pd, relevant_space_size, relevant_viewport);
+ //to performance optimize the whole widget, we are setting the objects that are outside the viewport to visibility false
+ //The code below ensures that things outside the viewport are always hidden, and things inside the viewport are visible
+ vis_segment_swap(&pd->object, cur, pd->prev_run);
+
+ _position_items(obj, pd, cur, relevant_space_size);
+
+ if (pd->prev_run.start_id != cur.start_id || pd->prev_run.end_id != cur.end_id)
+ {
+ ev.start_id = pd->prev_run.start_id = cur.start_id;
+ ev.end_id = pd->prev_run.end_id = cur.end_id;
+ efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_VISIBLE_RANGE_CHANGED, &ev);
+ }
+
+}
+
+static Eina_Value
+_rebuild_job_cb(void *data, Eina_Value v EINA_UNUSED, const Eina_Future *f EINA_UNUSED)
+{
+ MY_DATA_GET(data, pd);
+
+ if (!efl_alive_get(data)) return EINA_VALUE_EMPTY;
+
+ cache_require(data, pd);
+ recalc_absolut_size(data, pd);
+ position_content(data, pd);
+ pd->rebuild_absolut_size = NULL;
+
+ return EINA_VALUE_EMPTY;
+}
+
+static void
+schedule_recalc_absolut_size(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd)
+{
+ if (pd->rebuild_absolut_size) return;
+
+ pd->rebuild_absolut_size = efl_loop_job(efl_app_main_get());
+ eina_future_then(pd->rebuild_absolut_size, _rebuild_job_cb, obj);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_efl_ui_position_manager_entity_data_access_set(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd, void *obj_access_data, Efl_Ui_Position_Manager_Batch_Access_Entity obj_access, Eina_Free_Cb obj_access_free_cb, void *size_access_data, Efl_Ui_Position_Manager_Batch_Access_Size size_access, Eina_Free_Cb size_access_free_cb, int size)
+{
+ cache_invalidate(obj, pd);
+ pd->object.data = obj_access_data;
+ pd->object.access = obj_access;
+ pd->object.free_cb = obj_access_free_cb;
+ pd->min_size.data = size_access_data;
+ pd->min_size.access = size_access;
+ pd->min_size.free_cb = size_access_free_cb;
+ pd->size = size;
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_efl_ui_position_manager_entity_viewport_set(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd, Eina_Rect size)
+{
+ pd->viewport = size;
+
+ recalc_absolut_size(obj, pd);
+ position_content(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_efl_ui_position_manager_entity_scroll_position_set(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd, double x, double y)
+{
+ pd->scroll_position.x = x;
+ pd->scroll_position.y = y;
+ position_content(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_efl_ui_position_manager_entity_item_added(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, int added_index EINA_UNUSED, Efl_Gfx_Entity *subobj)
+{
+ if (pd->size == 0)
+ {
+ pd->prev_run.start_id = 0;
+ pd->prev_run.end_id = 0;
+ }
+ pd->size ++;
+ if (subobj)
+ {
+ efl_gfx_entity_visible_set(subobj, EINA_FALSE);
+ }
+ cache_invalidate(obj, pd);
+ schedule_recalc_absolut_size(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_efl_ui_position_manager_entity_item_removed(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, int removed_index EINA_UNUSED, Efl_Gfx_Entity *subobj)
+{
+ pd->size --;
+ if (subobj)
+ {
+ efl_gfx_entity_visible_set(subobj, EINA_TRUE);
+ }
+ cache_invalidate(obj, pd);
+ schedule_recalc_absolut_size(obj, pd);
+}
+
+EOLIAN static Eina_Rect
+_efl_ui_position_manager_list_efl_ui_position_manager_entity_position_single_item(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd, int idx)
+{
+ Eina_Rect geom;
+ Eina_Size2D space_size;
+ int relevant_space_size;
+ Eina_Size2D size;
+ Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
+
+ if (!pd->size) return EINA_RECT(0,0,0,0);
+
+ //space size contains the amount of space that is outside the viewport (either to the top or to the left)
+ space_size.w = (MAX(pd->abs_size.w - pd->viewport.w, 0))*pd->scroll_position.x;
+ space_size.h = (MAX(pd->abs_size.h - pd->viewport.h, 0))*pd->scroll_position.y;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(space_size.w >= 0 && space_size.h >= 0, EINA_RECT(0, 0, 0, 0));
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ relevant_space_size = space_size.h;
+ }
+ else
+ {
+ relevant_space_size = space_size.w;
+ }
+
+ geom = pd->viewport;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(_fill_buffer(&pd->min_size, idx, 1, NULL, size_buffer) == 1, EINA_RECT_EMPTY());
+
+ size = size_buffer[0].size;
+
+ if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
+ {
+ geom.y -= (relevant_space_size - cache_access(obj, pd, idx));
+ geom.h = size.h;
+ }
+ else
+ {
+ geom.x -= (relevant_space_size - cache_access(obj, pd, idx));
+ geom.w = size.w;
+ }
+ return geom;
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_efl_ui_position_manager_entity_item_size_changed(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd, int start_id EINA_UNUSED, int end_id EINA_UNUSED)
+{
+ cache_invalidate(obj, pd);
+ schedule_recalc_absolut_size(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_efl_ui_layout_orientable_orientation_set(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, Efl_Ui_Layout_Orientation dir)
+{
+ pd->dir = dir;
+ //in order to reset the state of the visible items, just hide everything and set the old segment accordingly
+ vis_change_segment(&pd->object, pd->prev_run.start_id, pd->prev_run.end_id, EINA_FALSE);
+ pd->prev_run.start_id = 0;
+ pd->prev_run.end_id = 0;
+
+ cache_invalidate(obj, pd);
+ cache_require(obj,pd);
+ recalc_absolut_size(obj, pd);
+ position_content(obj, pd);
+}
+
+EOLIAN static Efl_Ui_Layout_Orientation
+_efl_ui_position_manager_list_efl_ui_layout_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
+{
+ return pd->dir;
+}
+
+EOLIAN static void
+_efl_ui_position_manager_list_