diff options
author | Felipe Magno de Almeida <felipe@expertisesolutions.com.br> | 2017-09-07 12:07:29 +0900 |
---|---|---|
committer | SangHyeon Jade Lee <dltkdgus1764@gmail.com> | 2017-11-15 17:05:49 +0900 |
commit | 330d34d77401aa98ec9fb361170461d3e556c9dd (patch) | |
tree | 47c75970cfc9b54afe2bd67cb9bac21ed7e16754 | |
parent | d96f3bb4f398590adeb95d05110cf95b757a429c (diff) | |
download | efl-330d34d77401aa98ec9fb361170461d3e556c9dd.tar.gz |
elm: Add efl_ui_list view initial implementation
21 files changed, 3787 insertions, 12 deletions
diff --git a/config/default/base.src.in b/config/default/base.src.in index 10d7d0e6a5..7e9444c10c 100644 --- a/config/default/base.src.in +++ b/config/default/base.src.in @@ -2796,5 +2796,274 @@ group "Elm_Config" struct { } } } + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Efl.Ui.List"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Left"; + value "action" string: "move"; + value "params" string: "left"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Left"; + value "action" string: "move"; + value "params" string: "left_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Left"; + value "action" string: "move"; + value "params" string: "left"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Left"; + value "action" string: "move"; + value "params" string: "left_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Right"; + value "action" string: "move"; + value "params" string: "right"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Right"; + value "action" string: "move"; + value "params" string: "right_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Right"; + value "action" string: "move"; + value "params" string: "right"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Right"; + value "action" string: "move"; + value "params" string: "right_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Up"; + value "action" string: "move"; + value "params" string: "up"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Up"; + value "action" string: "move"; + value "params" string: "up_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Up"; + value "action" string: "move"; + value "params" string: "up"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Up"; + value "action" string: "move"; + value "params" string: "up_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Down"; + value "action" string: "move"; + value "params" string: "down"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Down"; + value "action" string: "move"; + value "params" string: "down_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Down"; + value "action" string: "move"; + value "params" string: "down"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Down"; + value "action" string: "move"; + value "params" string: "down_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Prior"; + value "action" string: "move"; + value "params" string: "prior"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Prior"; + value "action" string: "move"; + value "params" string: "prior"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Next"; + value "action" string: "move"; + value "params" string: "next"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Next"; + value "action" string: "move"; + value "params" string: "next"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Home"; + value "action" string: "move"; + value "params" string: "first"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Home"; + value "action" string: "move"; + value "params" string: "first"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "End"; + value "action" string: "move"; + value "params" string: "last"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_End"; + value "action" string: "move"; + value "params" string: "last"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Escape"; + value "action" string: "escape"; + value "params" string: ""; + } + } + } } } diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in index 5f5b5dd63b..18d3612548 100644 --- a/config/mobile/base.src.in +++ b/config/mobile/base.src.in @@ -2789,5 +2789,274 @@ group "Elm_Config" struct { } } } + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Efl.Ui.List"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Left"; + value "action" string: "move"; + value "params" string: "left"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Left"; + value "action" string: "move"; + value "params" string: "left_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Left"; + value "action" string: "move"; + value "params" string: "left"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Left"; + value "action" string: "move"; + value "params" string: "left_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Right"; + value "action" string: "move"; + value "params" string: "right"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Right"; + value "action" string: "move"; + value "params" string: "right_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Right"; + value "action" string: "move"; + value "params" string: "right"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Right"; + value "action" string: "move"; + value "params" string: "right_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Up"; + value "action" string: "move"; + value "params" string: "up"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Up"; + value "action" string: "move"; + value "params" string: "up_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Up"; + value "action" string: "move"; + value "params" string: "up"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Up"; + value "action" string: "move"; + value "params" string: "up_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Down"; + value "action" string: "move"; + value "params" string: "down"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Down"; + value "action" string: "move"; + value "params" string: "down_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Down"; + value "action" string: "move"; + value "params" string: "down"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Down"; + value "action" string: "move"; + value "params" string: "down_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Prior"; + value "action" string: "move"; + value "params" string: "prior"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Prior"; + value "action" string: "move"; + value "params" string: "prior"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Next"; + value "action" string: "move"; + value "params" string: "next"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Next"; + value "action" string: "move"; + value "params" string: "next"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Home"; + value "action" string: "move"; + value "params" string: "first"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Home"; + value "action" string: "move"; + value "params" string: "first"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "End"; + value "action" string: "move"; + value "params" string: "last"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_End"; + value "action" string: "move"; + value "params" string: "last"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Escape"; + value "action" string: "escape"; + value "params" string: ""; + } + } + } } } diff --git a/config/standard/base.src.in b/config/standard/base.src.in index 13497910ae..9781512539 100644 --- a/config/standard/base.src.in +++ b/config/standard/base.src.in @@ -2786,5 +2786,274 @@ group "Elm_Config" struct { } } } + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Efl.Ui.List"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Left"; + value "action" string: "move"; + value "params" string: "left"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Left"; + value "action" string: "move"; + value "params" string: "left_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Left"; + value "action" string: "move"; + value "params" string: "left"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Left"; + value "action" string: "move"; + value "params" string: "left_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Right"; + value "action" string: "move"; + value "params" string: "right"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Right"; + value "action" string: "move"; + value "params" string: "right_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Right"; + value "action" string: "move"; + value "params" string: "right"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Right"; + value "action" string: "move"; + value "params" string: "right_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Up"; + value "action" string: "move"; + value "params" string: "up"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Up"; + value "action" string: "move"; + value "params" string: "up_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Up"; + value "action" string: "move"; + value "params" string: "up"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Up"; + value "action" string: "move"; + value "params" string: "up_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Down"; + value "action" string: "move"; + value "params" string: "down"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Down"; + value "action" string: "move"; + value "params" string: "down_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Down"; + value "action" string: "move"; + value "params" string: "down"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 0; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Down"; + value "action" string: "move"; + value "params" string: "down_multi"; + group "modifiers" list { + group "Elm_Config_Binding_Modifier" struct { + value "mod" string: "Shift"; + value "flag" uchar: 1; + } + } + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Prior"; + value "action" string: "move"; + value "params" string: "prior"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Prior"; + value "action" string: "move"; + value "params" string: "prior"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Next"; + value "action" string: "move"; + value "params" string: "next"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Next"; + value "action" string: "move"; + value "params" string: "next"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Home"; + value "action" string: "move"; + value "params" string: "first"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Home"; + value "action" string: "move"; + value "params" string: "first"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "End"; + value "action" string: "move"; + value "params" string: "last"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_End"; + value "action" string: "move"; + value "params" string: "last"; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "select"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Escape"; + value "action" string: "escape"; + value "params" string: ""; + } + } + } } } diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 95d1cf8976..9a6571c283 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -170,6 +170,39 @@ elm_legacy_eolian_files = \ lib/elementary/elm_actionslider_part.eo \ lib/elementary/elm_bubble_part.eo \ lib/elementary/elm_fileselector_part.eo \ + lib/elementary/elm_multibuttonentry_part.eo \ + lib/elementary/elm_code_widget.eo \ + lib/elementary/efl_ui_text_interactive.eo \ + lib/elementary/efl_ui_text.eo \ + lib/elementary/efl_ui_text_editable.eo \ + lib/elementary/efl_ui_text_async.eo \ + lib/elementary/efl_config_global.eo \ + lib/elementary/efl_ui_clock.eo \ + lib/elementary/efl_ui_cursor.eo \ + lib/elementary/efl_ui_image_factory.eo \ + lib/elementary/efl_ui_focus_manager.eo \ + lib/elementary/efl_ui_focus_manager_calc.eo \ + lib/elementary/efl_ui_focus_manager_sub.eo \ + lib/elementary/efl_ui_focus_manager_root_focus.eo \ + lib/elementary/efl_ui_focus_object.eo \ + lib/elementary/efl_ui_focus_user.eo \ + lib/elementary/efl_ui_textpath.eo \ + lib/elementary/efl_ui_textpath_part.eo \ + lib/elementary/efl_ui_list.eo \ + lib/elementary/efl_ui_list_pan.eo \ + lib/elementary/efl_ui_layout_factory.eo \ + $(NULL) + +# Private classes (not exposed or shipped) +elm_private_eolian_files = \ + lib/elementary/efl_ui_internal_text_interactive.eo \ + lib/elementary/efl_ui_win_part.eo \ + tests/elementary/focus_test.eo \ + tests/elementary/focus_test_sub_main.eo \ + $(NULL) + +# Legacy classes - not part of public EO API +elm_legacy_eolian_files = \ lib/elementary/elm_access.eo \ lib/elementary/elm_actionslider.eo \ lib/elementary/elm_box.eo \ @@ -312,6 +345,7 @@ includesunstable_HEADERS = \ lib/elementary/elm_widget_thumb.h \ lib/elementary/elm_widget_toolbar.h \ lib/elementary/efl_ui_video_private.h \ + lib/elementary/efl_ui_list_private.h \ lib/elementary/elm_widget_web.h \ lib/elementary/efl_ui_clock.h \ lib/elementary/elm_code.h \ @@ -704,6 +738,8 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/efl_ui_focus_parent_provider_standard.c \ lib/elementary/efl_ui_focus_parent_provider_gen.c \ lib/elementary/elm_widget_item_static_focus.c \ + lib/elementary/efl_ui_list.c \ + lib/elementary/efl_ui_layout_factory.c \ $(NULL) diff --git a/src/examples/elementary/Makefile.am b/src/examples/elementary/Makefile.am index 25ea9a8c63..ff746b1446 100644 --- a/src/examples/elementary/Makefile.am +++ b/src/examples/elementary/Makefile.am @@ -175,7 +175,14 @@ efl_thread_2.c \ efl_thread_3.c \ efl_thread_4.c \ efl_thread_5.c \ -efl_thread_6.c +efl_thread_6.c \ +efl_thread_win32_1.c \ +efl_thread_win32_2.c \ +efl_thread_win32_3.c \ +efl_thread_win32_4.c \ +efl_ui_list_example_1.c \ +efl_ui_list_example_2.c \ +efl_ui_list_example_3.c if HAVE_CXX11 SRCS += \ @@ -206,7 +213,8 @@ twitter_example_01.edc \ evas3d_map_example.edc \ theme_example.edc \ layout_example.edc \ -codegen_example.edc +codegen_example.edc \ +efl_ui_list_example.edc EDJS = $(EDCS:%.edc=%.edj) @@ -228,13 +236,15 @@ files_DATA += \ layout_example.edj\ codegen_example.edj \ evas3d_map_example.edj \ - twitter_example_01.edj + twitter_example_01.edj \ + efl_ui_list_example.edj CLEANFILES = \ theme_example.edj \ layout_example.edj\ evas3d_map_example.edj \ - twitter_example_01.edj + twitter_example_01.edj \ + efl_ui_list_example.edj clean-local: rm -f *.epb *.cfg *.cfg.bkp @@ -363,7 +373,10 @@ efl_thread_2 \ efl_thread_3 \ efl_thread_4 \ efl_thread_5 \ -efl_thread_6 +efl_thread_6 \ +efl_ui_list_example_1 \ +efl_ui_list_example_2 \ +efl_ui_list_example_3 #benchmark3d #sphere-hunter @@ -566,7 +579,7 @@ screenshots: examples convert $(HTML_SS_DIR)/$${SS_FILE} $(LATEX_SS_DIR)/$${SS_FILE/.png/.eps} ; \ done -EXTRA_DIST = dict.txt layout_example.edc theme_example.edc codegen_example.edc evas3d_map_example.edc twitter_example_01.edc performance/layout.edc performance/background.png performance/target_texture.png sphere_hunter/sphere_hunter.edc sphere_hunter/score.jpg sphere_hunter/EFL_victory.png sphere_hunter/EFL_defeat.png codegen_example_generated.c codegen_example_generated.h codegen_example.edj prefs_example_01.epc prefs_example_02.epc prefs_example_03.epc prefs_example_03.edc +EXTRA_DIST = dict.txt layout_example.edc theme_example.edc codegen_example.edc evas3d_map_example.edc twitter_example_01.edc efl_ui_list_example.edc performance/layout.edc performance/background.png performance/target_texture.png sphere_hunter/sphere_hunter.edc sphere_hunter/score.jpg sphere_hunter/EFL_victory.png sphere_hunter/EFL_defeat.png codegen_example_generated.c codegen_example_generated.h codegen_example.edj prefs_example_01.epc prefs_example_02.epc prefs_example_03.epc prefs_example_03.edc examples: $(examples_PROGRAMS) $(EDJS) diff --git a/src/examples/elementary/efl_ui_list_example.edc b/src/examples/elementary/efl_ui_list_example.edc new file mode 100644 index 0000000000..3b46863b71 --- /dev/null +++ b/src/examples/elementary/efl_ui_list_example.edc @@ -0,0 +1,280 @@ + +#define FN_COL_DEFAULT 255 255 255 255; color3: 0 0 0 128 +#define FN_COL_DISABLE 21 21 21 255; color3: 255 255 255 25; +#define FN_COL_HIGHLIGHT 51 153 255 255; color2: 51 153 255 24; color3: 51 153 255 18 +#define FIXED_SIZE(_WIDTH, _HEIGHT) \ + min: _WIDTH _HEIGHT; max: _WIDTH _HEIGHT; fixed: 1 1; + + +collections { + +group { + name: "elm/list/item/custom"; + alias: "elm/list/item/default"; + data.item: "selectraise" "on"; + data.item: "focusraise" "on"; + parts { + part { name: "event"; type: RECT; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "base"; type: RECT; mouse_events: 0; + description { state: "default" 0.0; + color: 46 46 56 255; + color_class: "list_item_base_odd"; + } + description { state: "odd" 0.0; + color: 56 56 56 255; + color_class: "list_item_base_odd"; + } + } + program { + signal: "elm,state,odd"; source: "elm"; + action: STATE_SET "odd" 1.0; + target: "base"; + } + program { + signal: "elm,state,even"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "base"; + } + part { name: "sel_shadow"; mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_base"; mouse_events: 0; + description { state: "default" 0.0; + fill.smooth: 0; + visible: 0; + fill { size { relative: 0.0 1.0; offset: 120 0; } } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_bevel"; mouse_events: 0; + description { state: "default" 0.0; + fill.smooth: 0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + program { + signal: "elm,state,selected"; source: "elm"; + action: STATE_SET "selected" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + } + program { + signal: "elm,state,unselected"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + } + program { + signal: "elm,state,disabled"; source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "event"; + } + program { + signal: "elm,state,enabled"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "event"; + } + + //##// + part { name: "elm.text"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.offset: 2 3; + rel1.relative: 1.0 0.0; + rel1.to_x: "elm.swallow.icon"; + rel2.offset: -3 -3; + rel2.relative: 0.0 1.0; + rel2.to_x: "elm.swallow.end"; + color: FN_COL_DEFAULT; + color_class: "list_item"; + text { font: FN; size: 10; + min: 1 1; + ellipsis: -1; + align: 0.0 0.5; + text_class: "list_item"; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "label2"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + color: FN_COL_DISABLE; + color_class: "list_item_disabled"; + text { font: FN; size: 10; + text_source: "elm.text"; + align: 0.0 0.5; + text_class: "list_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "label3"; type: TEXT; mouse_events: 0; + effect: GLOW; + scale: 1; + description { state: "default" 0.0; + rel1.offset: -2 -3; + rel1.to: "elm.text"; + rel2.offset: 1 1; + rel2.to: "elm.text"; + color: FN_COL_HIGHLIGHT; + color_class: "list_item_selected"; + text { font: FN; size: 10; + text_source: "elm.text"; + align: 0.0 0.5; + text_class: "list_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + program { + signal: "elm,state,selected"; source: "elm"; + action: STATE_SET "selected" 0.0; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,unselected"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,disabled"; source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,enabled"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + //##// + part { name: "elm.swallow.icon"; type: SWALLOW; + description { state: "default" 0.0; + fixed: 1 0; + align: 0.0 0.5; + aspect: 1.0 1.0; + rel1.offset: 2 2; + rel2.relative: 0.0 1.0; + rel2.offset: 2 -3; + } + } + part { name: "elm.swallow.end"; type: SWALLOW; + description { state: "default" 0.0; + fixed: 1 0; + align: 1.0 0.5; + aspect: 1.0 1.0; + rel1.offset: -3 2; + rel1.relative: 1.0 0.0; + rel2.offset: -3 -3; + } + } + //##// + + part { name: "sel_shine"; mouse_events: 0; + description { state: "default" 0.0; + rel1.offset: 0 -2; + rel1.to: "sel_base"; + rel2.relative: 1.0 0.0; + rel2.offset: -1 2; + rel2.to: "sel_base"; + visible: 0; + FIXED_SIZE(69, 5) + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "event_block"; type: RECT; + description { state: "default" 0.0; + color: 0 0 0 0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + program { + signal: "elm,state,selected"; source: "elm"; + action: STATE_SET "selected" 0.0; + target: "sel_shine"; + } + program { + signal: "elm,state,unselected"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "sel_shine"; + } + program { + signal: "elm,state,disabled"; source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "event_block"; + } + program { + signal: "elm,state,enabled"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "event_block"; + } + } +} + +} + diff --git a/src/examples/elementary/efl_ui_list_example_1.c b/src/examples/elementary/efl_ui_list_example_1.c new file mode 100644 index 0000000000..9ac9adc19e --- /dev/null +++ b/src/examples/elementary/efl_ui_list_example_1.c @@ -0,0 +1,113 @@ +// gcc -o efl_ui_list_example_1 efl_ui_list_example_1.c `pkg-config --cflags --libs elementary` + +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#else +# define EFL_BETA_API_SUPPORT 1 +# define EFL_EO_API_SUPPORT 1 +#endif + +#include <Elementary.h> +#include <Efl.h> +#include <Eio.h> +#include <stdio.h> + +#define NUM_ITEMS 200 + +const char *styles[] = { + "odd", + "even" + }; + +char edj_path[PATH_MAX]; + +static void +_realized_cb(void *data, const Efl_Event *event) +{ + Efl_Ui_List_Item_Event *ie = event->info; + + if (!ie->layout) return; + + Efl_Ui_Layout *layout = ie->layout; + + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_obj_widget_focus_allow_set(layout, EINA_TRUE); +} + +/* +static void +_unrealized_cb(void *data EINA_UNUSED, const Efl_Event *event) +{ + Efl_Ui_List_Item_Event *ie = event->info; + + efl_ui_view_model_set(ie->layout, NULL); + efl_del(ie->layout); +} +*/ +static Efl_Model* +_make_model() +{ + Eina_Value vtext, vstyle; + Efl_Model_Item *model, *child; + unsigned int i, s; + char buf[256]; + + model = efl_add(EFL_MODEL_ITEM_CLASS, NULL); + eina_value_setup(&vtext, EINA_VALUE_TYPE_STRING); + eina_value_setup(&vstyle, EINA_VALUE_TYPE_STRING); + + for (i = 0; i < (NUM_ITEMS); i++) + { + s = i%2; + child = efl_model_child_add(model); + eina_value_set(&vstyle, styles[s]); + efl_model_property_set(child, "odd_style", &vstyle); + + snprintf(buf, sizeof(buf), "Item # %i", i); + eina_value_set(&vtext, buf); + efl_model_property_set(child, "name", &vtext); + } + + return model; +} + +EAPI_MAIN int +elm_main(int argc, char **argv) +{ + Efl_Ui_Layout_Factory *factory; + Evas_Object *win, *li; + Eo *model; + + win = elm_win_util_standard_add("viewlist", "Viewlist"); + elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); + + elm_win_autodel_set(win, EINA_TRUE); + + model = _make_model(); + + factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win); + efl_ui_model_connect(factory, "signal/elm,state,%v", "odd_style"); + efl_ui_model_connect(factory, "elm.text", "name"); + efl_ui_layout_factory_theme_config(factory, "list", "item", "default"); + + li = efl_add(EFL_UI_LIST_CLASS, win); + efl_ui_list_layout_factory_set(li, factory); + efl_ui_view_model_set(li, model); + + efl_event_callback_add(li, EFL_UI_LIST_EVENT_ITEM_REALIZED, _realized_cb, NULL); +// efl_event_callback_add(li, EFL_UI_LIST_EVENT_ITEM_UNREALIZED, _unrealized_cb, NULL); + + elm_win_resize_object_add(win, li); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + //showall + evas_object_show(li); + evas_object_resize(win, 320, 320); + evas_object_show(win); + + elm_run(); + + return 0; +} +ELM_MAIN() diff --git a/src/examples/elementary/efl_ui_list_example_2.c b/src/examples/elementary/efl_ui_list_example_2.c new file mode 100644 index 0000000000..9f37e322e5 --- /dev/null +++ b/src/examples/elementary/efl_ui_list_example_2.c @@ -0,0 +1,74 @@ +// gcc -o efl_ui_list_example_2 efl_ui_list_example_2.c `pkg-config --cflags --libs elementary` + +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# define EFL_BETA_API_SUPPORT 1 +# define EFL_EO_API_SUPPORT 1 +#endif + +#include <Elementary.h> +#include <Efl.h> +#include <Eio.h> +#include <stdio.h> + +#define EFL_MODEL_TEST_FILENAME_PATH "/tmp" + +static void +_realized_cb(void *data, const Efl_Event *event) +{ + Efl_Ui_List_Item_Event *ie = event->info; + Eo *imf = data; + printf("realize %d\n", ie->index); + + evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + + efl_ui_model_factory_connect(ie->layout, "elm.swallow.icon", imf); +} + +EAPI_MAIN int +elm_main(int argc, char **argv) +{ + Efl_Ui_Layout_Factory *factory; + Evas_Object *win; + Eo *imf, *model, *li; + char *dirname; + + win = elm_win_util_standard_add("viewlist", "Viewlist"); + elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); + + elm_win_autodel_set(win, EINA_TRUE); + + if (argv[1] != NULL) dirname = argv[1]; + else dirname = EFL_MODEL_TEST_FILENAME_PATH; + + model = efl_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(efl_added, dirname)); + factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win); + efl_ui_model_connect(factory, "elm.text", "filename"); + efl_ui_layout_factory_theme_config(factory, "list", "item", "default"); + + li = efl_add(EFL_UI_LIST_CLASS, win); + efl_ui_list_layout_factory_set(li, factory); + efl_ui_view_model_set(li, model); + + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + + + imf = efl_add(EFL_UI_IMAGE_FACTORY_CLASS, win); + efl_ui_model_connect(imf, "", "path"); //connect to "path" property + efl_event_callback_add(li, EFL_UI_LIST_EVENT_ITEM_REALIZED, _realized_cb, imf); + + elm_win_resize_object_add(win, li); + + //showall + evas_object_show(li); + evas_object_resize(win, 320, 320); + evas_object_show(win); + + elm_run(); + + return 0; +} +ELM_MAIN() diff --git a/src/examples/elementary/efl_ui_list_example_3.c b/src/examples/elementary/efl_ui_list_example_3.c new file mode 100644 index 0000000000..2be8cba149 --- /dev/null +++ b/src/examples/elementary/efl_ui_list_example_3.c @@ -0,0 +1,306 @@ +// gcc -o efl_ui_list_example_3 efl_ui_list_example_3.c `pkg-config --cflags --libs elementary` + +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# define EFL_BETA_API_SUPPORT 1 +# define EFL_EO_API_SUPPORT 1 +#endif + +#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED + +#include <Eo.h> +#include <Elementary.h> +#include <Efl.h> +#include <Eio.h> +#include <stdio.h> + +const char *subtexts[] = { + "Captain", + "Princess ", + "Actor", + "Translator", + "Jedi", + "Singer", + "Fighter" + }; + +const char *texts[] = { + "Morpheus", + "Leia", + "Chuck Norris", + "Nyota Uhura", + "Darth Vader", + "Elvis Presley", + "Chun-Li" + }; + +char edj_path[PATH_MAX]; + +struct _Priv_Data +{ + Eo *model; + Evas_Object *list1; + Evas_Object *list2; + Evas_Object *e_name; + Evas_Object *e_occ; +}; +typedef struct _Priv_Data Priv_Data; + +static void +_cleanup_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Priv_Data *priv = (Priv_Data*)data; + efl_unref(priv->model); +} + +static void +_bt_add_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Priv_Data *priv = (Priv_Data*)data; + Eina_Value vtext; + Efl_Model_Item *child; + + eina_value_setup(&vtext, EINA_VALUE_TYPE_STRING); + child = efl_model_child_add(priv->model); + + eina_value_set(&vtext, elm_object_text_get(priv->e_name)); + efl_model_property_set(child, "name", &vtext); + + eina_value_set(&vtext, elm_object_text_get(priv->e_occ)); + efl_model_property_set(child, "occupation", &vtext); + + eina_value_set(&vtext, "unselected"); + efl_model_property_set(child, "selected", &vtext); +} + +static void +_bt_del_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Priv_Data *priv = (Priv_Data*)data; + Efl_Object *l = NULL; + Eo *child = NULL; + + l = elm_interface_atspi_selection_selected_child_get(priv->list1, 0); + printf("selection %p\n", l); + if(l) + { + child = efl_ui_view_model_get(l); + efl_model_child_del(priv->model, child); + } + else + { + printf("no selection\n"); + } +} + +static void +_bt_none_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Evas_Object *li = data; + efl_ui_list_select_mode_set(li, ELM_OBJECT_SELECT_MODE_NONE); +} + +static void +_bt_donly_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Evas_Object *li = data; + efl_ui_list_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); +} + +static void +_bt_default_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Evas_Object *li = data; + efl_ui_list_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DEFAULT); +} + +static void +_bt_set_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Priv_Data *priv = data; + efl_ui_view_model_set(priv->list2, priv->model); +} + +static void +_bt_unset_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Evas_Object *li = data; + efl_ui_view_model_set(li, NULL); +} +static void +_realized_1_cb(void *data EINA_UNUSED, const Efl_Event *event) +{ + Efl_Ui_List_Item_Event *ie = event->info; + elm_layout_theme_set(ie->layout, "list", "item", "default"); + + evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + efl_ui_model_connect(ie->layout, "elm.text", "name"); + efl_ui_model_connect(ie->layout, "signal/elm,state,%v", "odd_style"); +} + +static void +_realized_2_cb(void *data EINA_UNUSED, const Efl_Event *event) +{ + Efl_Ui_List_Item_Event *ie = event->info; +// printf("relized 2\n"); + elm_layout_theme_set(ie->layout, "list", "item", "default"); + + evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + efl_ui_model_connect(ie->layout, "elm.text", "occupation"); +} + +static Efl_Model* +_make_model() +{ + Eina_Value vtext, vstyle; + Efl_Model_Item *model, *child; + unsigned int i, len; + + model = efl_add(EFL_MODEL_ITEM_CLASS, NULL); + eina_value_setup(&vtext, EINA_VALUE_TYPE_STRING); + eina_value_setup(&vstyle, EINA_VALUE_TYPE_STRING); + + len = sizeof(texts)/sizeof(const char*); + for (i = 0; i < (len); i++) + { + child = efl_model_child_add(model); + + i%2 ? eina_value_set(&vstyle, "even") : eina_value_set(&vstyle, "odd"); + efl_model_property_set(child, "odd_style", &vstyle); + + eina_value_set(&vtext, texts[(i % len)]); + efl_model_property_set(child, "name", &vtext); + + eina_value_set(&vtext, subtexts[(i % len)]); + efl_model_property_set(child, "occupation", &vtext); + + eina_value_set(&vtext, "unselected"); + efl_model_property_set(child, "selected", &vtext); + } + + return model; +} + +EAPI_MAIN int +elm_main(int argc, char **argv) +{ + Priv_Data *priv; + Evas_Object *win, *bx, *vbx, *bt; + + priv = alloca(sizeof(Priv_Data)); + memset(priv, 0, sizeof(Priv_Data)); + + win = elm_win_util_standard_add("viewlist", "Viewlist"); + elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); + elm_win_autodel_set(win, EINA_TRUE); + + bx = elm_box_add(win); + elm_box_horizontal_set(bx, EINA_TRUE); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + priv->model = _make_model(); + priv->list1 = efl_add(EFL_UI_LIST_CLASS, win, efl_ui_view_model_set(efl_added, priv->model)); + efl_event_callback_add(priv->list1, EFL_UI_LIST_EVENT_ITEM_REALIZED, _realized_1_cb, priv); + evas_object_size_hint_weight_set(priv->list1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(priv->list1, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(bx, priv->list1); + + priv->list2 = efl_add(EFL_UI_LIST_CLASS, win, efl_ui_view_model_set(efl_added, priv->model)); + efl_event_callback_add(priv->list2, EFL_UI_LIST_EVENT_ITEM_REALIZED, _realized_2_cb, priv->list2); + evas_object_size_hint_weight_set(priv->list2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(priv->list2, EVAS_HINT_FILL, EVAS_HINT_FILL); + + vbx = elm_box_add(win); + elm_box_pack_end(bx, vbx); + + bt = elm_label_add(win); + elm_object_text_set(bt, "Name:"); + elm_box_pack_end(vbx, bt); + evas_object_show(bt); + + priv->e_name = elm_entry_add(win); + elm_box_pack_end(vbx, priv->e_name); + elm_object_text_set(priv->e_name, "Neo"); + evas_object_size_hint_weight_set(priv->e_name, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(priv->e_name, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(priv->e_name); + + bt = elm_label_add(win); + elm_object_text_set(bt, "Occupation:"); + elm_box_pack_end(vbx, bt); + evas_object_show(bt); + + priv->e_occ = elm_entry_add(win); + elm_box_pack_end(vbx, priv->e_occ); + elm_object_text_set(priv->e_occ, "Chosen"); + evas_object_size_hint_weight_set(priv->e_occ, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(priv->e_occ, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(priv->e_occ); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Add Item"); + evas_object_smart_callback_add(bt, "clicked", _bt_add_clicked, priv); + evas_object_show(bt); + elm_box_pack_end(vbx, bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Delete Item"); + evas_object_smart_callback_add(bt, "clicked", _bt_del_clicked, priv); + evas_object_show(bt); + elm_box_pack_end(vbx, bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Select None"); + evas_object_smart_callback_add(bt, "clicked", _bt_none_clicked, priv->list2); + evas_object_show(bt); + elm_box_pack_end(vbx, bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Select DisplayOnly"); + evas_object_smart_callback_add(bt, "clicked", _bt_donly_clicked, priv->list2); + evas_object_show(bt); + elm_box_pack_end(vbx, bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Select Default"); + evas_object_smart_callback_add(bt, "clicked", _bt_default_clicked, priv->list2); + evas_object_show(bt); + elm_box_pack_end(vbx, bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Model Set"); + evas_object_smart_callback_add(bt, "clicked", _bt_set_clicked, priv); + evas_object_show(bt); + elm_box_pack_end(vbx, bt); + + + bt = elm_button_add(win); + elm_object_text_set(bt, "Model Unset"); + evas_object_smart_callback_add(bt, "clicked", _bt_unset_clicked, priv->list2); + evas_object_show(bt); + elm_box_pack_end(vbx, bt); + + + + elm_box_pack_end(bx, priv->list2); + + evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, priv); + + //showall + evas_object_show(priv->list1); + evas_object_show(priv->list2); + evas_object_show(bx); + evas_object_show(vbx); + evas_object_resize(win, 400, 320); + evas_object_show(win); + + elm_run(); + + return 0; +} +ELM_MAIN() diff --git a/src/examples/elementary/layout_model_connect.c b/src/examples/elementary/layout_model_connect.c index b856692246..aa34478f08 100644 --- a/src/examples/elementary/layout_model_connect.c +++ b/src/examples/elementary/layout_model_connect.c @@ -127,7 +127,6 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) elm_object_part_content_set(panes, "right", bxr); /*Label widget */ - _label_init(win, bxr, "FILENAME:"); priv->label = _label_init(win, bxr, ""); efl_ui_model_connect(priv->label, "default", "path"); //connect "default" to "filename" property diff --git a/src/lib/eina/eina_inarray.c b/src/lib/eina/eina_inarray.c index 80bb3ea059..efeb73c56e 100644 --- a/src/lib/eina/eina_inarray.c +++ b/src/lib/eina/eina_inarray.c @@ -107,8 +107,8 @@ static int _eina_inarray_log_dom = -1; } \ while(0) -static void -_eina_inarray_setup(Eina_Inarray *array, unsigned int member_size, unsigned int step) +void +eina_inarray_setup(Eina_Inarray *array, unsigned int member_size, unsigned int step) { EINA_MAGIC_SET(array, EINA_MAGIC_INARRAY); array->version = EINA_ARRAY_VERSION; @@ -347,7 +347,7 @@ eina_inarray_new(unsigned int member_size, unsigned int step) ret = malloc(sizeof(*ret)); if (!ret) return NULL; - _eina_inarray_setup(ret, member_size, step); + eina_inarray_setup(ret, member_size, step); return ret; } @@ -381,7 +381,7 @@ eina_inarray_step_set(Eina_Inarray *array, return; } - _eina_inarray_setup(array, member_size, step); + eina_inarray_setup(array, member_size, step); } EAPI void diff --git a/src/lib/eina/eina_inarray.h b/src/lib/eina/eina_inarray.h index 2ac314fb1d..d32bd612fb 100644 --- a/src/lib/eina/eina_inarray.h +++ b/src/lib/eina/eina_inarray.h @@ -235,6 +235,26 @@ struct _Eina_Inarray }; /** + * @brief Initializes a inline array in-place. + * @details This initializes an array where members are inlined in a sequence. Each + * member has @a member_size bytes. + * + * @param[in] array Pointer to uninitialized array + * @param[in] member_size The size of each member in the array + * @param[in] step The step size by which to resize the array, do this using the following + * extra amount + * @return The new inline array table, otherwise @c NULL on failure + * + * @note If the @a step is @c 0, then a safe default is chosen. + * + * @see eina_inarray_free() + * + * @since 1.2 + */ +EAPI void eina_inarray_setup(Eina_Inarray* array, unsigned int member_size, + unsigned int step); + +/** * @brief Creates a new inline array. * @details This creates a new array where members are inlined in a sequence. Each * member has @a member_size bytes. diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 806e04821e..a57ca5095a 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -284,6 +284,10 @@ EAPI extern Elm_Version *elm_version; # include <efl_ui_text_async.eo.h> # include <efl_ui_clock.eo.h> # include <efl_ui_image_factory.eo.h> +# include <efl_ui_slider_interval.eo.h> +# include <efl_ui_layout_factory.eo.h> +# include <efl_ui_list.eo.h> +# include <efl_ui_list_pan.eo.h> #endif /* include deprecated calls last of all */ diff --git a/src/lib/elementary/efl_ui_image_factory.c b/src/lib/elementary/efl_ui_image_factory.c index c2a87c4546..480be5d536 100644 --- a/src/lib/elementary/efl_ui_image_factory.c +++ b/src/lib/elementary/efl_ui_image_factory.c @@ -39,6 +39,7 @@ _efl_ui_image_factory_efl_ui_factory_create(Eo *obj EINA_UNUSED, Efl_Ui_Image_Fa EINA_SAFETY_ON_NULL_RETURN_VAL(pd->property, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + ui_view = efl_add(EFL_UI_IMAGE_CLASS, parent); efl_ui_view_model_set(ui_view, model); efl_ui_model_connect(ui_view, "filename", pd->property); diff --git a/src/lib/elementary/efl_ui_layout_factory.c b/src/lib/elementary/efl_ui_layout_factory.c new file mode 100644 index 0000000000..e9f721fd63 --- /dev/null +++ b/src/lib/elementary/efl_ui_layout_factory.c @@ -0,0 +1,123 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include <Elementary.h> +#include "elm_priv.h" + +#define MY_CLASS EFL_UI_LAYOUT_FACTORY_CLASS +#define MY_CLASS_NAME "Efl.Ui.Layout_Factory" + +typedef struct _Efl_Ui_Layout_Factory_Data +{ + Eina_Array *layouts; + Eina_Hash *connects; + Eina_Stringshare *klass; + Eina_Stringshare *group; + Eina_Stringshare *style; +} Efl_Ui_Layout_Factory_Data; + +Eina_Bool +_model_connect(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata) +{ + Eo *layout = fdata; + Eina_Stringshare *name = key; + Eina_Stringshare *property = data; + + efl_ui_model_connect(layout, name, property); + + return EINA_TRUE; +} + +EOLIAN static Eo * +_efl_ui_layout_factory_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Factory_Data *pd) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + + pd->klass = NULL; + pd->group = NULL; + pd->style = NULL; + pd->layouts = eina_array_new(8); + pd->connects = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del)); + + return obj; +} + +EOLIAN static void +_efl_ui_layout_factory_efl_object_destructor(Eo *obj, Efl_Ui_Layout_Factory_Data *pd) +{ + Eina_Array_Iterator iterator; + Eo *layout; + unsigned int i; + + eina_stringshare_del(pd->klass); + eina_stringshare_del(pd->group); + eina_stringshare_del(pd->style); + + EINA_ARRAY_ITER_NEXT(pd->layouts, i, layout, iterator) + efl_parent_set(layout, NULL); + + eina_array_free(pd->layouts); + eina_hash_free(pd->connects); + + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static Efl_Gfx * +_efl_ui_layout_factory_efl_ui_factory_create(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd + , Efl_Model *model, Efl_Gfx *parent) +{ + Efl_Gfx *layout; + EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + + if (eina_array_count(pd->layouts)) + { + layout = eina_array_pop(pd->layouts); + efl_parent_set(layout, parent); + efl_ui_view_model_set(layout, model); + } + else + { + layout = efl_add(EFL_UI_LAYOUT_CLASS, parent, + efl_ui_view_model_set(efl_added, model), + elm_layout_theme_set(efl_added, pd->klass, pd->group, pd->style)); + eina_hash_foreach(pd->connects, _model_connect, layout); + } + + return layout; +} + +EOLIAN static void +_efl_ui_layout_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd, Efl_Gfx *layout) +{ + efl_ui_view_model_set(layout, NULL); + eina_array_push(pd->layouts, layout); +} + +EOLIAN static void +_efl_ui_layout_factory_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd + , const char *name, const char *property) +{ + Eina_Stringshare *ss_name, *ss_prop; + ss_name = eina_stringshare_add(name); + + if (property == NULL) + { + eina_hash_del(pd->connects, ss_name, NULL); + return; + } + + ss_prop = eina_stringshare_add(property); + eina_stringshare_del(eina_hash_set(pd->connects, ss_name, ss_prop)); +} + +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) +{ + eina_stringshare_replace(&pd->klass, klass); + eina_stringshare_replace(&pd->group, group); + eina_stringshare_replace(&pd->style, style); +} + +#include "efl_ui_layout_factory.eo.c" diff --git a/src/lib/elementary/efl_ui_layout_factory.eo b/src/lib/elementary/efl_ui_layout_factory.eo new file mode 100644 index 0000000000..e712900d1c --- /dev/null +++ b/src/lib/elementary/efl_ui_layout_factory.eo @@ -0,0 +1,22 @@ +class Efl.Ui.Layout_Factory (Efl.Object, Efl.Ui.Factory) +{ + [[Efl Ui Layout Factory class]] + methods { + theme_config { + [[]] + params { + klass: string; [[The class of the group.]] + group: string; [[The group.]] + style: string; [[The style to used.]] + } + } + } + + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Ui.Factory.create; + Efl.Ui.Factory.release; + Efl.Ui.Model.Connect.connect; + } +} diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c new file mode 100644 index 0000000000..41cc478f13 --- /dev/null +++ b/src/lib/elementary/efl_ui_list.c @@ -0,0 +1,1737 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED +#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED +#define EFL_ACCESS_SELECTION_PROTECTED + +#include <Elementary.h> +#include "efl_ui_list_private.h" + +#include <assert.h> + +#define MY_CLASS EFL_UI_LIST_CLASS +#define MY_CLASS_NAME "Efl.Ui.List" + +#define MY_PAN_CLASS EFL_UI_LIST_PAN_CLASS + +#define SIG_CHILD_ADDED "child,added" +#define SIG_CHILD_REMOVED "child,removed" +#define SELECTED_PROP "selected" +#define AVERAGE_SIZE_INIT 10 + +static const Evas_Smart_Cb_Description _smart_callbacks[] = { + {SIG_CHILD_ADDED, ""}, + {SIG_CHILD_REMOVED, ""}, + {NULL, NULL} +}; + +void _efl_ui_list_custom_layout(Efl_Ui_List *); +void _efl_ui_list_item_select_set(Efl_Ui_List_Item *, Eina_Bool); +Eina_Bool _efl_ui_list_item_select_clear(Eo *); +static void _item_calc(Efl_Ui_List_Data *, Efl_Ui_List_Item *); +static void _layout_realize(Efl_Ui_List_Data *, Efl_Ui_List_Item *); +static void _layout_unrealize(Efl_Ui_List_Data *, Efl_Ui_List_Item *); +static Eina_Bool _update_items(Eo *, Efl_Ui_List_Data *); +static void _insert_at(Efl_Ui_List_Data* pd, int index, Efl_Model* child); +static void _remove_at(Efl_Ui_List_Data* pd, int index); + +static Eina_Bool _key_action_move(Evas_Object *obj, const char *params); +static Eina_Bool _key_action_select(Evas_Object *obj, const char *params); +static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params); + +static const Elm_Action key_actions[] = { + {"move", _key_action_move}, + {"select", _key_action_select}, + {"escape", _key_action_escape}, + {NULL, NULL} +}; + +static inline Eina_Bool +_horiz(Efl_Orient dir) +{ + return dir % 180 == EFL_ORIENT_RIGHT; +} + +EOLIAN static void +_efl_ui_list_pan_elm_pan_pos_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd, Evas_Coord x, Evas_Coord y) +{ + Evas_Coord ox, oy, ow, oh, cw; + Efl_Ui_List_Data *pd = psd->wpd; + Efl_Ui_List_Item **litem; + + EINA_SAFETY_ON_NULL_RETURN(pd); + if (((x == pd->pan.x) && (y == pd->pan.y))) return; + + evas_object_geometry_get(pd->obj, &ox, &oy, &ow, &oh); + if (_horiz(pd->orient)) + { + pd->pan.move_diff += x - pd->pan.x; + cw = ow / 4; + } + else + { + pd->pan.move_diff += y - pd->pan.y; + cw = oh / 4; + } + + pd->pan.x = x; + pd->pan.y = y; + + if (abs(pd->pan.move_diff) > cw) + { + pd->pan.move_diff = 0; + _update_items(obj, pd); + } + else + { + EINA_INARRAY_FOREACH(&pd->items.array, litem) + evas_object_move((*litem)->layout, ((*litem)->x + 0 - pd->pan.x), ((*litem)->y + 0 - pd->pan.y)); + } +} + +EOLIAN static void +_efl_ui_list_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y) +{ + Efl_Ui_List_Data *pd = psd->wpd; + + if (x) *x = pd->pan.x; + if (y) *y = pd->pan.y; +} + +EOLIAN static void +_efl_ui_list_pan_elm_pan_pos_max_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y) +{ + Evas_Coord ow, oh; + + elm_interface_scrollable_content_viewport_geometry_get + (psd->wobj, NULL, NULL, &ow, &oh); + ow = psd->wpd->minw - ow; + if (ow < 0) ow = 0; + oh = psd->wpd->minh - oh; + if (oh < 0) oh = 0; + + if (x) *x = ow; + if (y) *y = oh; +} + +EOLIAN static void +_efl_ui_list_pan_elm_pan_pos_min_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y) +{ + if (x) *x = 0; + if (y) *y = 0; +} + +EOLIAN static void +_efl_ui_list_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h) +{ + Efl_Ui_List_Data *pd = psd->wpd; + EINA_SAFETY_ON_NULL_RETURN(pd); + + if (w) *w = pd->minw; + if (h) *h = pd->minh; +} + +EOLIAN static void +_efl_ui_list_pan_efl_object_destructor(Eo *obj, Efl_Ui_List_Pan_Data *psd) +{ + efl_data_unref(psd->wobj, psd->wpd); + efl_destructor(efl_super(obj, MY_PAN_CLASS)); +} + +#include "efl_ui_list_pan.eo.c" + +static Eina_Bool +_efl_model_properties_has(Efl_Model *model, Eina_Stringshare *propfind) +{ + const Eina_Array *properties; + Eina_Array_Iterator iter_prop; + Eina_Stringshare *property; + Eina_Bool ret = EINA_FALSE; + unsigned i = 0; + + EINA_SAFETY_ON_NULL_RETURN_VAL(model, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(propfind, EINA_FALSE); + + properties = efl_model_properties_get(model); + + EINA_ARRAY_ITER_NEXT(properties, i, property, iter_prop) + { + if (property == propfind) + { + ret = EINA_TRUE; + break; + } + } + return ret; +} + +static void +_child_added_cb(void *data, const Efl_Event *event) +{ + Efl_Model_Children_Event* evt = event->info; + Efl_Ui_List *obj = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + int index = evt->index - pd->realized.start; + + pd->item_count++; + if (index >= 0 && index <= pd->realized.slice) + _insert_at(pd, index, evt->child); + else + evas_object_smart_changed(pd->obj); +} + +static void +_child_removed_cb(void *data, const Efl_Event *event) +{ + Efl_Model_Children_Event* evt = event->info; + Efl_Ui_List *obj = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + int index = evt->index - pd->realized.start; + + pd->item_count--; + if (index >= 0 && index < pd->realized.slice) + _remove_at(pd, index); + else + evas_object_smart_changed(pd->obj); +} + +static void +_on_item_focused(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED) +{ + Efl_Ui_List_Item *item = data; + + EFL_UI_LIST_DATA_GET_OR_RETURN(item->list, pd); + + if (!_elm_config->item_select_on_focus_disable) + _efl_ui_list_item_select_set(item, EINA_TRUE); +} + +static Eina_Bool +_long_press_cb(void *data) +{ + Efl_Ui_List_Item *item = data; + + item->long_timer = NULL; + item->longpressed = EINA_TRUE; + if (item->layout) + efl_event_callback_legacy_call(item->layout, EFL_UI_EVENT_LONGPRESSED, item); + + return ECORE_CALLBACK_CANCEL; +} + +static void +_on_item_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info) +{ + Evas_Event_Mouse_Down *ev = event_info; + Efl_Ui_List_Item *item = data; + + EFL_UI_LIST_DATA_GET_OR_RETURN(item->list, pd); + + if (ev->button != 1) return; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) pd->on_hold = EINA_TRUE; + else pd->on_hold = EINA_FALSE; + if (pd->on_hold) return; + + item->down = EINA_TRUE; + assert(item->longpressed == EINA_FALSE); + + ecore_timer_del(item->long_timer); + item->long_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press_cb, item); +} + +static void +_on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info) +{ + Evas_Event_Mouse_Down *ev = event_info; + Efl_Ui_List_Item *item = data; + + EFL_UI_LIST_DATA_GET_OR_RETURN(item->list, pd); + + if (ev->button != 1) return; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) pd->on_hold = EINA_TRUE; + else pd->on_hold = EINA_FALSE; + if (pd->on_hold || !item->down) return; + + item->down = EINA_FALSE; + ELM_SAFE_FREE(item->long_timer, ecore_timer_del); + + if (!item->longpressed) + { + if (pd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS && item->selected) + return; + + _efl_ui_list_item_select_set(item, EINA_TRUE); + } + else + item->longpressed = EINA_FALSE; +} + +static void +_item_selected_then(void * data, Efl_Event const* event) +{ + Efl_Ui_List_Item *item = data; + EINA_SAFETY_ON_NULL_RETURN(item); + Eina_Stringshare *selected; + const Eina_Value_Type *vtype; + Eina_Value *value = (Eina_Value *)((Efl_Future_Event_Success*)event->info)->value; + + vtype = eina_value_type_get(value); + + if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE) + { + eina_value_get(value, &selected); + Eina_Bool s = (strcmp(selected, "selected") ? EINA_FALSE : EINA_TRUE); + EFL_UI_LIST_DATA_GET_OR_RETURN(item->list, pd); + + if (item->selected == s) return; + + item->selected = s; + item->future = NULL; + + if (item->selected) + pd->selected_items = eina_list_append(pd->selected_items, item); + else + pd->selected_items = eina_list_remove(pd->selected_items, item); + } +} + +static void +_count_then(void * data, Efl_Event const* event) +{ + Efl_Ui_List_Data *pd = data; + EINA_SAFETY_ON_NULL_RETURN(pd); + int *count = ((Efl_Future_Event_Success*)event->info)->value; + + pd->item_count = *count; + _update_items(pd->obj, pd); +} + +static void +_count_error(void * data, Efl_Event const* event EINA_UNUSED) +{ + Efl_Ui_List_Data *pd = data; + EINA_SAFETY_ON_NULL_RETURN(pd); +} + +static void +_item_style_property_then(void * data, Efl_Event const* event) +{ + Efl_Ui_List_Item *item = data; + EINA_SAFETY_ON_NULL_RETURN(item); + char *style = NULL; + + Eina_Value *value = (Eina_Value *)((Efl_Future_Event_Success*)event->info)->value; + const Eina_Value_Type *vtype = eina_value_type_get(value); + + item->future = NULL; + if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE) + eina_value_get(value, &style); + + elm_object_style_set(item->layout, style); +} + +static void +_item_property_error(void * data, Efl_Event const* event EINA_UNUSED) +{ + Efl_Ui_List_Item *item = data; + EINA_SAFETY_ON_NULL_RETURN(item); + + item->future = NULL; +} + +static void +_efl_model_properties_changed_cb(void *data, const Efl_Event *event) +{ + Efl_Ui_List_Item *item = data; + EINA_SAFETY_ON_NULL_RETURN(item); + Efl_Model_Property_Event *evt = event->info; + Eina_Array_Iterator it; + Eina_Stringshare *prop, *sprop; + unsigned int i; + + if (!evt->changed_properties) return; + + sprop = eina_stringshare_add(SELECTED_PROP); + EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it) + { + if (prop == sprop) + { + item->future = efl_model_property_get(item->model, sprop); + efl_future_then(item->future, &_item_selected_then, &_item_property_error, NULL, item); + } + } +} + +static void +_item_min_calc(Efl_Ui_List_Data *pd, Efl_Ui_List_Item *item, Evas_Coord h, Evas_Coord w) +{ + Efl_Ui_List_Item *litem, **it; + + if(_horiz(pd->orient)) + { + pd->realized.w -= item->minw; + pd->realized.w += w; + if(pd->realized.h <= h) + pd->realized.h = h; + else if (pd->realized.h < item->minh) + { + pd->realized.h = h; + EINA_INARRAY_FOREACH(&pd->items.array, it) + { + litem = *it; + if (!litem) continue; + if (pd->realized.h < litem->minh) + pd->realized.h = litem->minh; + + if (litem != item && litem->minh == item->minh) + break; + } + } + } + else + { + pd->realized.h -= item->minh; + pd->realized.h += h; + if(pd->realized.w <= w) + pd->realized.w = w; + else if (pd->realized.w == item->minw) + { + pd->realized.w = w; + EINA_INARRAY_FOREACH(&pd->items.array, it) + { + litem = *it; + if (!litem) continue; + if (pd->realized.w < litem->minw) + pd->realized.w = litem->minw; + + if (litem != item && litem->minw == item->minw) + break; + } + } + } + + item->minw = w; + item->minh = h; +} + +static void +_on_item_size_hint_change(void *data, Evas *e EINA_UNUSED, + Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Efl_Ui_List_Item *item = data; + EINA_SAFETY_ON_NULL_RETURN(item); +// if (obj != item->layout) { printf("NOOOOOOOOOOOOOOOOOOOOOO\n"); return; } + + EFL_UI_LIST_DATA_GET_OR_RETURN(item->list, pd); + _item_calc(pd, item); + evas_object_smart_changed(item->list); +} + +static void +_layout_realize(Efl_Ui_List_Data *pd, Efl_Ui_List_Item *item) +{ + Efl_Ui_List_Item_Event evt; + + efl_ui_view_model_set(item->layout, item->model); + + evt.child = item->model; + evt.layout = item->layout; + evt.index = item->index; + efl_event_callback_call(item->list, EFL_UI_LIST_EVENT_ITEM_REALIZED, &evt); + + evas_object_show(item->layout); + _item_calc(pd, item); +} + +static void +_layout_unrealize(Efl_Ui_List_Data *pd, Efl_Ui_List_Item *item) +{ + Efl_Ui_List_Item_Event evt; + EINA_SAFETY_ON_NULL_RETURN(item); + + if (item->future) + { + efl_future_cancel(item->future); + item->future = NULL; + } + + /* TODO:calculate new min */ + _item_min_calc(pd, item, 0, 0); + + evt.child = item->model; + evt.layout = item->layout; + evt.index = item->index; + efl_event_callback_call(item->list, EFL_UI_LIST_EVENT_ITEM_UNREALIZED, &evt); + efl_ui_view_model_set(item->layout, NULL); + + evas_object_hide(item->layout); + evas_object_move(item->layout, -9999, -9999); +} + +static Efl_Ui_List_Item* +_child_setup(Efl_Ui_List_Data *pd, Efl_Model *model + , Eina_Inarray* recycle_layouts, int idx) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL); + + Efl_Ui_List_Item* item = calloc(1, sizeof(Efl_Ui_List_Item)); + + assert(model != NULL); + assert(item->layout == NULL); + assert(item->list == NULL); + + item->list = pd->obj; + item->future = NULL; + item->model = efl_ref(model); + if (recycle_layouts && eina_inarray_count(recycle_layouts)) + item->layout = *(void**)eina_inarray_pop(recycle_layouts); + else + { + Eina_Stringshare *sselected = eina_stringshare_add("selected"); + item->layout = efl_ui_factory_create(pd->factory, item->model, pd->obj); + +// if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE && _efl_model_properties_has(item->model, sselected)) + efl_ui_model_connect(item->layout, "signal/elm,state,%v", "selected"); + + eina_stringshare_del(sselected); + } + item->index = idx + pd->realized.start; + item->minw = item->minh = 0; + + elm_widget_sub_object_add(pd->obj, item->layout); + evas_object_smart_member_add(item->layout, pd->pan.obj); + +// FIXME: really need get it in model? + Eina_Stringshare *style_prop = eina_stringshare_add("style"); + if (_efl_model_properties_has(item->model, style_prop)) + { + item->future = efl_model_property_get(item->model, style_prop); + efl_future_then(item->future, &_item_style_property_then, &_item_property_error, NULL, item); + } + eina_stringshare_del(style_prop); +// + _layout_realize(pd, item); + + efl_event_callback_add(item->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, item); + efl_event_callback_add(item->layout, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, _on_item_focused, item); + + evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_DOWN, _on_item_mouse_down, item); + evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item); + evas_object_event_callback_add(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, item); + + if (item->selected) + pd->selected_items = eina_list_append(pd->selected_items, item); + + return item; +} + +static void +_child_release(Efl_Ui_List_Data* pd, Efl_Ui_List_Item** oitem, Eina_Inarray* recycle_layouts) +{ + Efl_Ui_List_Item* item = *oitem; + + evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, item); + efl_event_callback_del(item->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, item); + evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_DOWN, _on_item_mouse_down, item); + evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item); + + efl_event_callback_del(item->layout, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, _on_item_focused, item); + + if (item->selected) + pd->selected_items = eina_list_remove(pd->selected_items, item); + + item->list = NULL; + + _layout_unrealize(pd, item); + + efl_unref(item->model); + // discard elm_layout to thrash to be able to reuse it + assert(item->layout != NULL); + + if (recycle_layouts) + eina_inarray_push(recycle_layouts, &item->layout); + else + efl_ui_factory_release(pd->factory, item->layout); + + item->layout = NULL; + + if (_horiz(pd->orient)) + pd->realized.w -= item->w; + else + pd->realized.h -= item->h; + + free(item); + *oitem = NULL; +} + +static void +_remove_at(Efl_Ui_List_Data* pd, int index) +{ + Efl_Ui_List_Item **to_first, **from_first; + int i, j; + + // fits, just move around + to_first = pd->items.array.members; + to_first += index; + from_first = to_first + 1; + + _child_release(pd, to_first, NULL); + + memmove(to_first, from_first, sizeof(Efl_Ui_List_Item*)*(pd->items.array.len - index - 1)); + + for(i = index, j = 0; i < (int)pd->items.array.len-1; ++i, ++j) + { + to_first[j]->index--; + } + eina_inarray_pop(&pd->items.array); + + pd->realized.slice--; + evas_object_smart_changed(pd->obj); +} + +static void +_insert_at(Efl_Ui_List_Data* pd, int index, Efl_Model* child) +{ + Efl_Ui_List_Item **members, *item; + int i; + + item = _child_setup(pd, child, NULL, index - pd->realized.start); + eina_inarray_insert_at(&pd->items.array, index, &item); + + // fits, just move around + members = pd->items.array.members; + + for(i = index+1; i < (int)pd->items.array.len; ++i) + { + members[i]->index++; + } + + pd->realized.slice++; + evas_object_smart_changed(pd->obj); +} + +static void +_resize_children(Efl_Ui_List_Data* pd, int removing_before, int removing_after, + Eina_Accessor* acc) +{ + Eina_Inarray recycle_layouts; + unsigned to_begin, from_begin, copy_size; + unsigned idx; + + eina_inarray_setup(&recycle_layouts, sizeof(Efl_Ui_Layout*), 0); + + EINA_SAFETY_ON_NULL_RETURN(pd); + EINA_SAFETY_ON_NULL_RETURN(acc); + ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd); + + assert(pd->realized.slice == eina_inarray_count(&pd->items.array)); + // received slice start is after older slice start + if (removing_before > 0) + { + int i = 0; + while (i != removing_before) + { + Efl_Ui_List_Item** members = pd->items.array.members; + _child_release(pd, &members[i], &recycle_layouts); + ++i; + } + to_begin = 0; + from_begin = removing_before; + } + else + { + to_begin = -removing_before; + from_begin = 0; + } + + if (removing_after > 0) + { + int i = pd->realized.slice - removing_after; + while (i != pd->realized.slice) + { + Efl_Ui_List_Item** members = pd->items.array.members; + _child_release(pd, &members[i], &recycle_layouts); + ++i; + } + copy_size = eina_inarray_count(&pd->items.array) + - (from_begin + removing_after); + } + else + { + copy_size = eina_inarray_count(&pd->items.array) - from_begin; + } + + if (removing_after + removing_before >= 0) + { + if (from_begin != to_begin) + { + Efl_Ui_List_Item** from = pd->items.array.members; + Efl_Ui_List_Item** to = pd->items.array.members; + from += from_begin; + to += to_begin; + memmove(to, from, copy_size*sizeof(Efl_Ui_List_Item*)); + } + memset(&((Efl_Ui_List_Item**)pd->items.array.members)[copy_size+to_begin], 0, (eina_inarray_count(&pd->items.array) - (copy_size+to_begin))*sizeof(Efl_Ui_List_Item*)); + memset(&((Efl_Ui_List_Item**)pd->items.array.members)[0], 0, to_begin*sizeof(Efl_Ui_List_Item*)); + pd->items.array.len -= removing_before + removing_after; + } + else + { + Efl_Ui_List_Item** data = calloc(1, pd->outstanding_slice.slice*sizeof(Efl_Ui_List_Item*)); + Efl_Ui_List_Item** from_first = pd->items.array.members; + from_first += from_begin; + Efl_Ui_List_Item** to_first = data + to_begin; + memcpy(to_first, from_first, copy_size*sizeof(Efl_Ui_List_Item*)); + free(pd->items.array.members); + pd->items.array.members = data; + pd->items.array.len = pd->items.array.max = pd->outstanding_slice.slice; + } + + pd->realized.start = pd->outstanding_slice.slice_start; + pd->realized.slice = pd->outstanding_slice.slice; + + idx = 0; + while(removing_before < 0) + { + Efl_Ui_List_Item** members = pd->items.array.members; + Efl_Ui_List_Item** item = &members[idx]; + + // initialize item + void* model = NULL; + int r = eina_accessor_data_get(acc, idx + pd->realized.start - pd->outstanding_slice.slice_start, &model); + assert(r != EINA_FALSE); + assert(model != NULL); + + *item = _child_setup(pd, model, &recycle_layouts, idx); + + idx++; + removing_before++; + } + + idx = copy_size + to_begin; + while(removing_after < 0) + { + Efl_Ui_List_Item** members = pd->items.array.members; + Efl_Ui_List_Item** item = &members[idx]; + + // initialize item + void* model = NULL; + int r = eina_accessor_data_get(acc, idx + pd->realized.start - pd->outstanding_slice.slice_start, &model); + assert(r != EINA_FALSE); + assert(model != NULL); + + *item = _child_setup(pd, model, &recycle_layouts, idx); + + idx++; + removing_after++; + } + + { + Efl_Ui_Layout **layout; + EINA_INARRAY_FOREACH(&recycle_layouts, layout) + { + efl_ui_factory_release(pd->factory, *layout); + } + free(recycle_layouts.members); + } +} + +static void +_children_then(void * data, Efl_Event const* event) +{ + Efl_Ui_List_Data *pd = data; + Eina_Accessor *acc = (Eina_Accessor*)((Efl_Future_Event_Success*)event->info)->value; + int removing_before = -pd->realized.start + pd->outstanding_slice.slice_start; + int removing_after = pd->realized.start + pd->realized.slice + - (pd->outstanding_slice.slice_start + pd->outstanding_slice.slice); + + pd->future = NULL; + // If current slice doesn't reach new slice + if(pd->realized.start + pd->realized.slice < pd->outstanding_slice.slice_start + || pd->outstanding_slice.slice_start + pd->outstanding_slice.slice < pd->realized.start) + { + removing_before = pd->realized.slice; + removing_after = -pd->outstanding_slice.slice; + } + + _resize_children(pd, removing_before, removing_after, acc); + evas_object_smart_changed(pd->obj); +} + +static void +_efl_ui_list_children_free(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + Eina_Inarray recycle_layouts; + + Efl_Ui_List_Item** item; + Efl_Ui_Layout** layout; + + EINA_SAFETY_ON_NULL_RETURN(pd); + eina_inarray_setup(&recycle_layouts, sizeof(Efl_Ui_Layout*), 0); + + EINA_INARRAY_FOREACH(&pd->items.array, item) + { + _child_release(pd, item, &recycle_layouts); + } + + eina_inarray_resize(&pd->items.array, 0); + EINA_INARRAY_FOREACH(&recycle_layouts, layout) + { + efl_ui_factory_release(pd->factory, *layout); + } + + pd->realized.slice = 0; + pd->realized.start = 0; + free(recycle_layouts.members); +} + +static void +_children_error(void * data EINA_UNUSED, Efl_Event const* event EINA_UNUSED) +{ + Efl_Ui_List_Data *pd = data; + EINA_SAFETY_ON_NULL_RETURN(pd); + pd->future = NULL; +} + +static void +_show_region_hook(void *data EINA_UNUSED, Evas_Object *obj) +{ + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + Eina_Rect r = elm_obj_widget_show_region_get(obj); + r.x += pd->pan.x; + r.y += pd->pan.y; + elm_interface_scrollable_content_region_show(obj, r.x, r.y, r.w, r.h); +} + +EOLIAN static void +_efl_ui_list_select_mode_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Elm_Object_Select_Mode mode) +{ + /* Eina_Array_Iterator iterator; */ + /* Efl_Ui_List_Item *item; */ + /* unsigned int i; */ + + if (pd->select_mode == mode) + return; + + /* if (pd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) */ + /* { */ + /* EINA_ARRAY_ITER_NEXT(pd->items.array, i, item, iterator) */ + /* { */ + /* if (item->selected) */ + /* elm_layout_signal_emit(item->layout, "elm,state,selected", "elm"); */ + + /* efl_ui_model_connect(item->layout, "signal/elm,state,%v", "selected"); */ + /* } */ + /* } */ + /* else if (mode == ELM_OBJECT_SELECT_MODE_NONE) */ + /* { */ + /* EINA_ARRAY_ITER_NEXT(pd->items.array, i, item, iterator) */ + /* { */ + /* if (item->selected) */ + /* elm_layout_signal_emit(item->layout, "elm,state,unselected", "elm"); */ + + /* efl_ui_model_connect(item->layout, "signal/elm,state,%v", NULL); */ + /* } */ + /* } */ + pd->select_mode = mode; +} + +EOLIAN static Elm_Object_Select_Mode +_efl_ui_list_select_mode_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + return pd->select_mode; +} + +EOLIAN static void +_efl_ui_list_default_style_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Eina_Stringshare *style) +{ + eina_stringshare_replace(&pd->style, style); +} + +EOLIAN static Eina_Stringshare * +_efl_ui_list_default_style_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + return pd->style; +} + +//FIXME update layout +EOLIAN static void +_efl_ui_list_homogeneous_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Eina_Bool homogeneous) +{ + pd->homogeneous = homogeneous; +} + +EOLIAN static Eina_Bool +_efl_ui_list_homogeneous_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + return pd->homogeneous; +} + +EOLIAN static Efl_Ui_Theme_Apply +_efl_ui_list_elm_widget_theme_apply(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED) +{ + return elm_obj_widget_theme_apply(efl_super(obj, MY_CLASS)); +} + +EOLIAN static void +_efl_ui_list_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_List_Data *pd) +{ + if (pd->recalc) return; + + _efl_ui_list_custom_layout(obj); +} + +EOLIAN static void +_efl_ui_list_efl_gfx_position_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Position2D p) +{ + if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, p.x, p.y)) + return; + + efl_gfx_position_set(efl_super(obj, MY_CLASS), p); + + evas_object_move(pd->hit_rect, p.x, p.y); + evas_object_move(pd->pan.obj, p.x - pd->pan.x, p.y - pd->pan.y); + evas_object_smart_changed(pd->obj); +} + +EOLIAN static void +_efl_ui_list_elm_interface_scrollable_region_bring_in(Eo *obj, Efl_Ui_List_Data *pd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + elm_interface_scrollable_region_bring_in(efl_super(obj, MY_CLASS), x + pd->pan.x, y + pd->pan.y, w, h); +} + +EOLIAN static void +_efl_ui_list_efl_gfx_size_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Size2D size) +{ + Evas_Coord oldw, oldh; + Eina_Bool load = EINA_FALSE; + + if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, size.w, size.h)) + return; + + evas_object_geometry_get(obj, NULL, NULL, &oldw, &oldh); + efl_gfx_size_set(efl_super(obj, MY_CLASS), size); + evas_object_resize(pd->hit_rect, size.w, size.h); + + if (_horiz(pd->orient)) + { + if (size.w != oldw) load = EINA_TRUE; + } + else + { + if (size.h != oldh) load = EINA_TRUE; + } + + if (load && _update_items(obj, pd)) + return; + + evas_object_smart_changed(pd->obj); +} + +EOLIAN static void +_efl_ui_list_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_List_Data *pd, Evas_Object *member) +{ + efl_canvas_group_member_add(efl_super(obj, MY_CLASS), member); + + if (pd->hit_rect) + evas_object_raise(pd->hit_rect); +} + +EOLIAN static void +_efl_ui_list_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED) +{ + Eina_Size2D min = { -1, }, max = {-1,}; + Evas_Coord vmw = 0, vmh = 0; + + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); + + min = efl_gfx_size_hint_combined_min_get(obj); + evas_object_size_hint_max_get(obj, &max.w, &max.h); + edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh); + + min.w = vmw; + min.h = vmh; + + if ((max.w > 0) && (min.w > max.w)) + min.w = max.w; + if ((max.h > 0) && (min.h > max.h)) + min.h = max.h; + + evas_object_size_hint_min_set(obj, min.w, min.h); + evas_object_size_hint_max_set(obj, max.w, max.h); +} + +EOLIAN static void +_efl_ui_list_efl_canvas_group_group_add(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED) +{ + Efl_Ui_List_Pan_Data *pan_data; + Evas_Coord minw, minh; + + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); + + efl_canvas_group_add(efl_super(obj, MY_CLASS)); + elm_widget_sub_object_parent_add(obj); + + elm_widget_can_focus_set(obj, EINA_TRUE); + + pd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_data_set(pd->hit_rect, "_elm_leaveme", obj); + evas_object_smart_member_add(pd->hit_rect, obj); + elm_widget_sub_object_add(obj, pd->hit_rect); + + /* common scroller hit rectangle setup */ + evas_object_color_set(pd->hit_rect, 0, 0, 0, 0); + evas_object_show(pd->hit_rect); + evas_object_repeat_events_set(pd->hit_rect, EINA_TRUE); + + elm_widget_on_show_region_hook_set(obj, NULL, _show_region_hook, NULL); + + if (!elm_layout_theme_set(obj, "list", "base", elm_widget_style_get(obj))) + CRI("Failed to set layout!"); + + elm_interface_scrollable_objects_set(obj, wd->resize_obj, pd->hit_rect); + elm_interface_scrollable_bounce_allow_set + (obj, EINA_FALSE, _elm_config->thumbscroll_bounce_enable); + + pd->mode = ELM_LIST_COMPRESS; + + elm_interface_atspi_accessible_type_set(obj, ELM_ATSPI_TYPE_DISABLED); + pd->pan.obj = efl_add(MY_PAN_CLASS, evas_object_evas_get(obj)); + pan_data = efl_data_scope_get(pd->pan.obj, MY_PAN_CLASS); + efl_data_ref(obj, MY_CLASS); + pan_data->wobj = obj; + pan_data->wpd = pd; + pd->pan.x = 0; + pd->pan.y = 0; + + elm_interface_scrollable_extern_pan_set(obj, pd->pan.obj); + evas_object_show(pd->pan.obj); + + edje_object_size_min_calc(wd->resize_obj, &minw, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + + elm_layout_sizing_eval(obj); +} + +EOLIAN static void +_efl_ui_list_efl_canvas_group_group_del(Eo *obj, Efl_Ui_List_Data *pd) +{ + _efl_ui_list_children_free(obj, pd); + + ELM_SAFE_FREE(pd->pan.obj, evas_object_del); + efl_canvas_group_del(efl_super(obj, MY_CLASS)); +} + +EOLIAN static Efl_Ui_Focus_Manager* +_efl_ui_list_elm_widget_focus_manager_create(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root) +{ + if (!pd->manager) + pd->manager = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, obj, + efl_ui_focus_manager_root_set(efl_added, root)); + + return pd->manager; +} + +EOLIAN static Eo * +_efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd) +{ + Efl_Ui_Focus_Manager *manager; + + obj = efl_constructor(efl_super(obj, MY_CLASS)); + pd->obj = obj; + efl_canvas_object_type_set(obj, MY_CLASS_NAME); + evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks); + elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_LIST); + + eina_inarray_setup(&pd->items.array, sizeof(Efl_Ui_List_Item*), 0); + + manager = elm_obj_widget_focus_manager_create(obj, obj); + efl_composite_attach(obj, manager); + _efl_ui_focus_manager_redirect_events_add(manager, obj); + + pd->style = eina_stringshare_add(elm_widget_style_get(obj)); + + pd->factory = NULL; + pd->orient = EFL_ORIENT_DOWN; + pd->align.h = 0; + pd->align.v = 0; + + return obj; +} + +EOLIAN static void +_efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd) +{ + efl_unref(pd->model); + eina_stringshare_del(pd->style); + + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static void +_efl_ui_list_layout_factory_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Efl_Ui_Factory *factory) +{ + //TODO: clean all current layouts?? + if (pd->factory) + efl_unref(pd->factory); + + pd->factory = efl_ref(factory); +} + +EOLIAN static void +_efl_ui_list_efl_ui_view_model_set(Eo *obj, Efl_Ui_List_Data *pd, Efl_Model *model) +{ + if (pd->model == model) + return; + + if (pd->future) + { + efl_future_cancel(pd->future); + pd->future = NULL; + } + + if (pd->model) + { + efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, obj); + efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, _child_removed_cb, obj); + efl_unref(pd->model); + _efl_ui_list_children_free(obj, pd); + pd->model = NULL; + pd->item_count = 0; + } + + if (!pd->factory) + pd->factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, obj); + + if (model) + { + pd->model = model; + efl_ref(pd->model); + efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, obj); + efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, _child_removed_cb, obj); + efl_future_then(efl_model_children_count_get(pd->model), &_count_then, &_count_error, NULL, pd); + } + + evas_object_smart_changed(pd->obj); +} + +EOLIAN static Efl_Model * +_efl_ui_list_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + return pd->model; +} + +EOLIAN const Elm_Atspi_Action * +_efl_ui_list_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED) +{ + static Elm_Atspi_Action atspi_actions[] = { + { "move,prior", "move", "prior", _key_action_move}, + { "move,next", "move", "next", _key_action_move}, + { "move,up", "move", "up", _key_action_move}, + { "move,up,multi", "move", "up_multi", _key_action_move}, + { "move,down", "move", "down", _key_action_move}, + { "move,down,multi", "move", "down_multi", _key_action_move}, + { "move,first", "move", "first", _key_action_move}, + { "move,last", "move", "last", _key_action_move}, + { "select", "select", NULL, _key_action_select}, + { "select,multi", "select", "multi", _key_action_select}, + { "escape", "escape", NULL, _key_action_escape}, + { NULL, NULL, NULL, NULL } + }; + return &atspi_actions[0]; +} + +EOLIAN Eina_List* +_efl_ui_list_elm_interface_atspi_accessible_children_get(Eo *obj, Efl_Ui_List_Data *pd) +{ + Efl_Ui_List_Item **litem; + Eina_List *ret = NULL, *ret2 = NULL; + + EINA_INARRAY_FOREACH(&pd->items.array, litem) + ret = eina_list_append(ret, (*litem)->layout); + + ret2 = elm_interface_atspi_accessible_children_get(efl_super(obj, MY_CLASS)); + return eina_list_merge(ret, ret2); +} + +EOLIAN int +_efl_ui_list_efl_access_selection_selected_children_count_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + return eina_list_count(pd->selected_items); +} + +EOLIAN Eo* +_efl_ui_list_efl_access_selection_selected_child_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int child_index) +{ + if(child_index < (int) eina_list_count(pd->selected_items)) + { + Efl_Ui_List_Item* items = eina_list_nth(pd->selected_items, child_index); + return items[child_index].layout; + } + else + return NULL; +} + +EOLIAN Eina_Bool +_efl_ui_list_efl_access_selection_child_select(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED) +{ + /* if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE) */ + /* { */ + /* if(child_index < eina_inlist_count(&pd->items.array)) */ + /* { */ + /* Efl_Ui_List_Item* items = pd->items.array.members; */ + /* _efl_ui_list_item_select_set(&items[child_index], EINA_TRUE); */ + /* return EINA_TRUE; */ + /* } */ + /* } */ + return EINA_FALSE; +} + +EOLIAN Eina_Bool +_efl_ui_list_efl_access_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED) +{ +/* Efl_Ui_List_Item *item = eina_list_nth(pd->selected, child_index); */ +/* if (item) */ +/* { */ +/* _efl_ui_list_item_select_set(pd, item->layout, EINA_FALSE); */ +/* return EINA_TRUE; */ +/* } */ + return EINA_FALSE; +} + +EOLIAN Eina_Bool +_efl_ui_list_efl_access_selection_is_child_selected(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int child_index) +{ + Efl_Ui_List_Item **item = eina_inarray_nth(&pd->items.array, child_index); + EINA_SAFETY_ON_NULL_RETURN_VAL(*item, EINA_FALSE); + return (*item)->selected; +} + +EOLIAN Eina_Bool +_efl_ui_list_efl_access_selection_all_children_select(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + Efl_Ui_List_Item **item; + + if (pd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) + return EINA_FALSE; + + EINA_INARRAY_FOREACH(&pd->items.array, item) + _efl_ui_list_item_select_set(*item, EINA_TRUE); + + return EINA_TRUE; +} + +EOLIAN Eina_Bool +_efl_ui_list_efl_access_selection_clear(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + Efl_Ui_List_Item *item; + Eina_List *l; + + if (pd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) + return EINA_FALSE; + + EINA_LIST_FOREACH(pd->selected_items, l, item) + _efl_ui_list_item_select_set(item, EINA_FALSE); + + return EINA_TRUE; +} + +EOLIAN Eina_Bool +_efl_ui_list_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED) +{ + /* Efl_Ui_List_Item *item = eina_array_data_get(pd->items.array, child_index); */ + /* if (item) */ + /* { */ + /* _efl_ui_list_item_select_set(item, EINA_FALSE); */ + /* return EINA_TRUE; */ + /* } */ + + return EINA_FALSE; +} + +static Eina_Bool +_key_action_move(Evas_Object *obj, const char *params) +{ + EFL_UI_LIST_DATA_GET_OR_RETURN_VAL(obj, pd, EINA_FALSE); + const char *dir = params; + + Evas_Coord page_x, page_y; + Evas_Coord v_w, v_h; + Evas_Coord x, y; + + elm_interface_scrollable_content_pos_get(obj, &x, &y); + elm_interface_scrollable_page_size_get(obj, &page_x, &page_y); + elm_interface_scrollable_content_viewport_geometry_get(obj, NULL, NULL, &v_w, &v_h); + +/* + Efl_Ui_List_Item *item = NULL; + Elm_Object_Item *oitem = NULL; + Elm_Layout *eoit = NULL; + if (!strcmp(dir, "up") || !strcmp(dir, "up_multi")) + { + if (!elm_widget_focus_next_get(obj, ELM_FOCUS_UP, &eoit, &oitem)) + return EINA_FALSE; + } + else if (!strcmp(dir, "down") || !strcmp(dir, "down_multi")) + { + if (!elm_widget_focus_next_get(obj, ELM_FOCUS_DOWN, &eoit, &oitem)) + return EINA_FALSE; + } + else if (!strcmp(dir, "first")) + { + item = eina_list_data_get(pd->items); + x = 0; + y = 0; + elm_widget_focus_next_object_set(obj, item->layout, ELM_FOCUS_UP); + } + else if (!strcmp(dir, "last")) + { + item = eina_list_data_get(eina_list_last(pd->items)); + elm_obj_pan_pos_max_get(pd->pan.obj, &x, &y); + } + else */ + if (!strcmp(dir, "prior")) + { + if (_horiz(pd->orient)) + { + if (page_x < 0) + x -= -(page_x * v_w) / 100; + else + x -= page_x; + } + else + { + if (page_y < 0) + y -= -(page_y * v_h) / 100; + else + y -= page_y; + } + } + else if (!strcmp(dir, "next")) + { + if (_horiz(pd->orient)) + { + if (page_x < 0) + x += -(page_x * v_w) / 100; + else + x += page_x; + } + else + { + if (page_y < 0) + y += -(page_y * v_h) / 100; + else + y += page_y; + } + } + else return EINA_FALSE; + + elm_interface_scrollable_content_pos_set(obj, x, y, EINA_TRUE); + return EINA_TRUE; +} + +static Eina_Bool +_key_action_select(Evas_Object *obj, const char *params EINA_UNUSED) +{ + EFL_UI_LIST_DATA_GET_OR_RETURN_VAL(obj, pd, EINA_FALSE); + + /* Eo *focused = efl_ui_focus_manager_focused(pd->manager); */ + /* if (focused) */ + /* _efl_ui_list_item_select_set(item, EINA_TRUE); */ + + return EINA_FALSE; +} + +static Eina_Bool +_key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED) +{ + return _efl_ui_list_item_select_clear(obj); +} + +EOLIAN static Eina_Bool +_efl_ui_list_elm_widget_widget_event(Eo *obj, Efl_Ui_List_Data *pd, Efl_Event const* event, Evas_Object *src/*, Evas_Callback_Type type, void *event_info*/) +{ + (void)src; + Evas_Event_Key_Down *ev = event->info; + + if (event->desc != EFL_EVENT_KEY_DOWN) return EINA_FALSE; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + if (!eina_inarray_count(&pd->items.array)) return EINA_FALSE; + + if (!_elm_config_key_binding_call(obj, MY_CLASS_NAME, ev, key_actions)) + return EINA_FALSE; + + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; +} + +Eina_Bool +_efl_ui_list_item_select_clear(Eo *obj) +{ + Eina_List *li; + Efl_Ui_List_Item *item; + EFL_UI_LIST_DATA_GET_OR_RETURN_VAL(obj, pd, EINA_FALSE); + + EINA_LIST_FOREACH(pd->selected_items, li, item) + _efl_ui_list_item_select_set(item, EINA_FALSE); + + return EINA_TRUE; +} + +void +_efl_ui_list_item_select_set(Efl_Ui_List_Item *item, Eina_Bool selected) +{ + Eina_Stringshare *sprop, *svalue; + + assert(item != NULL); + EFL_UI_LIST_DATA_GET_OR_RETURN(item->list, pd); + + if ((pd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || + (pd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)) + return; + + selected = !!selected; + /* if (!item->model || item->selected == selected) return; */ + assert(item->model != NULL); + + sprop = eina_stringshare_add(SELECTED_PROP); + svalue = (selected ? eina_stringshare_add("selected") : eina_stringshare_add("unselected")); + + if (_efl_model_properties_has(item->model, sprop)) + { + Eina_Value v; + eina_value_setup(&v, EINA_VALUE_TYPE_STRINGSHARE); + eina_value_set(&v, svalue); + efl_model_property_set(item->model, sprop, &v); + eina_value_flush(&v); + } + eina_stringshare_del(sprop); + eina_stringshare_del(svalue); + + /* //TODO I need call this event or catch only by model connect event? */ + if (selected) + efl_event_callback_legacy_call(item->layout, EFL_UI_EVENT_SELECTED, item); + else + efl_event_callback_legacy_call(item->layout, EFL_UI_EVENT_UNSELECTED, item); +} + +static void +_item_calc(Efl_Ui_List_Data *pd, Efl_Ui_List_Item *item) +{ + int pad[4]; + Eina_Size2D min; + + min = efl_gfx_size_hint_combined_min_get(item->layout); + efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]); + efl_gfx_size_hint_weight_get(item->layout, &item->wx, &item->wy); + + if (item->wx < 0) item->wx = 0; + if (item->wy < 0) item->wy = 0; + + min.w += pad[0] + pad[1]; + min.h += pad[2] + pad[3]; + + pd->weight.x += item->wx; + pd->weight.y += item->wy; + + _item_min_calc(pd, item, min.h, min.w); + evas_object_size_hint_min_set(item->layout, min.w, min.h); +} + +static Eina_Bool +_update_items(Eo *obj, Efl_Ui_List_Data *pd) +{ + int want_slice, want_slice_start = 0; + Evas_Coord w = 0, h = 0; + Eina_Bool horz = _horiz(pd->orient); + + /* assert(!pd->future); */ + if (pd->future) + { + efl_future_cancel(pd->future); + pd->future = NULL; + } + + int average_item_size = eina_inarray_count(&pd->items.array) ? (horz ? pd->realized.w : pd->realized.h) / eina_inarray_count(&pd->items.array) : AVERAGE_SIZE_INIT; + if(!average_item_size) + average_item_size = AVERAGE_SIZE_INIT; + + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + if (horz) + { + want_slice = (w / average_item_size) * 2; + want_slice_start = (pd->pan.x / average_item_size) - (want_slice / 4); + if(want_slice_start < 0) + want_slice_start = 0; + } + else + { + want_slice = (h / average_item_size) * 2; + want_slice_start = (pd->pan.y / average_item_size) - (want_slice / 4); + if(want_slice_start < 0) + want_slice_start = 0; + } + + assert(want_slice_start >= 0); + if(want_slice < 8) + want_slice = 8; + if(want_slice_start + want_slice > pd->item_count) + { + if(want_slice > pd->item_count) + want_slice = pd->item_count; + want_slice_start = pd->item_count - want_slice; + assert(want_slice_start >= 0); + } + + if(want_slice != 0) + { + pd->outstanding_slice.slice_start = want_slice_start; + pd->outstanding_slice.slice = want_slice; + pd->future = efl_model_children_slice_get(pd->model, want_slice_start, want_slice); + efl_future_then(pd->future, &_children_then, &_children_error, NULL, pd); + } + + return EINA_TRUE; +} + +void +_efl_ui_list_custom_layout(Efl_Ui_List *ui_list) +{ + EFL_UI_LIST_DATA_GET_OR_RETURN(ui_list, pd); + Efl_Ui_List_Item *litem, **it; + + Eina_Bool horiz = _horiz(pd->orient), zeroweight = EINA_FALSE; + Evas_Coord ow, oh, want, minw, minh; + int boxx, boxy, boxw, boxh, length, pad, extra = 0, rounding = 0; + int boxl = 0, boxr = 0, boxt = 0, boxb = 0; + double cur_pos = 0, scale, box_align[2], weight[2] = { 0, 0 }; + Eina_Bool box_fill[2] = { EINA_FALSE, EINA_FALSE }; + int count = 0; + Eina_List *order = NULL; + + ELM_WIDGET_DATA_GET_OR_RETURN(ui_list, wd); + + evas_object_geometry_get(ui_list, &boxx, &boxy, &boxw, &boxh); + efl_gfx_size_hint_margin_get(ui_list, &boxl, &boxr, &boxt, &boxb); + + scale = evas_object_scale_get(ui_list); + // Box align: used if "item has max size and fill" or "no item has a weight" + // Note: cells always expand on the orthogonal direction + box_align[0] = pd->align.h; + box_align[1] = pd->align.v; + if (box_align[0] < 0) + { + box_fill[0] = EINA_TRUE; + box_align[0] = 0.5; + } + if (box_align[1] < 0) + { + box_fill[1] = EINA_TRUE; + box_align[1] = 0.5; + } + + count = eina_inarray_count(&pd->items.array); + + elm_interface_scrollable_content_viewport_geometry_get + (ui_list, NULL, NULL, &ow, &oh); + // box outer margin + boxw -= boxl + boxr; + boxh -= boxt + boxb; + boxx += boxl; + boxy += boxt; + + int average_item_size = eina_inarray_count(&pd->items.array) ? (/*horz*/ EINA_FALSE ? pd->realized.w : pd->realized.h) / eina_inarray_count(&pd->items.array) : AVERAGE_SIZE_INIT; + if(!average_item_size) + average_item_size = AVERAGE_SIZE_INIT; + + // total space & available space + if (horiz) + { + length = boxw; + want = pd->realized.w; + pad = pd->pad.scalable ? (pd->pad.h * scale) : pd->pad.h; + + // padding can not be squeezed (note: could make it an option) + length -= pad * (count - 1); + // available space. if <0 we overflow + extra = length - want; + + minw = pd->realized.w + boxl + boxr + pad * (count - 1); + minh = pd->realized.h + boxt + boxb; + if (pd->item_count > count) + minw = pd->item_count * average_item_size; + } + else + { + length = boxh; + want = pd->realized.h; + pad = pd->pad.scalable ? (pd->pad.v * scale) : pd->pad.v; + + // padding can not be squeezed (note: could make it an option) + length -= pad * (count - 1); + // available space. if <0 we overflow + extra = length - want; + + minw = pd->realized.w + boxl + boxr; + minh = pd->realized.h + pad * (count - 1) + boxt + boxb; + if (pd->item_count > count) + minh = pd->item_count * average_item_size; + } + + if (pd->minh != minh || pd->minw != minw) + { + pd->minw = minw; + pd->minh = minh; + + efl_event_callback_legacy_call(pd->pan.obj, ELM_PAN_EVENT_CHANGED, NULL); + } + + evas_object_size_hint_min_set(wd->resize_obj, pd->minw, pd->minh); + + if (extra < 0) extra = 0; + + weight[0] = pd->weight.x; + weight[1] = pd->weight.y; + if (EINA_DBL_EQ(weight[!horiz], 0)) + { + if (box_fill[!horiz]) + { + // box is filled, set all weights to be equal + zeroweight = EINA_TRUE; + } + else + { + // move bounding box according to box align + cur_pos = extra * box_align[!horiz]; + } + weight[!horiz] = count; + } + + cur_pos += average_item_size * pd->realized.start; + // scan all items, get their properties, calculate total weight & min size + EINA_INARRAY_FOREACH(&pd->items.array, it) + { + litem = *it; + double cx, cy, cw, ch, x, y, w, h; + double align[2]; + int item_pad[4]; + Eina_Size2D max; + + assert(litem->layout != NULL); + efl_gfx_size_hint_align_get(litem->layout, &align[0], &align[1]); + max = efl_gfx_size_hint_max_get(litem->layout); + efl_gfx_size_hint_margin_get(litem->layout, &item_pad[0], &item_pad[1], &item_pad[2], &item_pad[3]); + + if (align[0] < 0) align[0] = -1; + if (align[1] < 0) align[1] = -1; + if (align[0] > 1) align[0] = 1; + if (align[1] > 1) align[1] = 1; + + if (max.w <= 0) max.w = INT_MAX; + if (max.h <= 0) max.h = INT_MAX; + if (max.w < litem->minw) max.w = litem->minw; + if (max.h < litem->minh) max.h = litem->minh; + + /* // extra rounding up (compensate cumulative error) */ + /* if ((id == (count - 1)) && (cur_pos - floor(cur_pos) >= 0.5)) */ + /* rounding = 1; */ + + if (horiz) + { + cx = boxx + cur_pos; + cy = boxy; + cw = litem->minw + rounding + (zeroweight ? 1.0 : litem->wx) * extra / weight[0]; + ch = boxh; + cur_pos += cw + pad; + } + else + { + cx = boxx; + cy = boxy + cur_pos; + cw = boxw; + ch = litem->minh + rounding + (zeroweight ? 1.0 : litem->wy) * extra / weight[1]; + cur_pos += ch + pad; + } + + // horizontally + if (max.w < INT_MAX) + { + w = MIN(MAX(litem->minw - item_pad[0] - item_pad[1], max.w), cw); + if (align[0] < 0) + { + // bad case: fill+max are not good together + x = cx + ((cw - w) * box_align[0]) + item_pad[0]; + } + else + x = cx + ((cw - w) * align[0]) + item_pad[0]; + } + else if (align[0] < 0) + { + // fill x + w = cw - item_pad[0] - item_pad[1]; + x = cx + item_pad[0]; + } + else + { + w = litem->minw - item_pad[0] - item_pad[1]; + x = cx + ((cw - w) * align[0]) + item_pad[0]; + } + + // vertically + if (max.h < INT_MAX) + { + h = MIN(MAX(litem->minh - item_pad[2] - item_pad[3], max.h), ch); + if (align[1] < 0) + { + // bad case: fill+max are not good together + y = cy + ((ch - h) * box_align[1]) + item_pad[2]; + } + else + y = cy + ((ch - h) * align[1]) + item_pad[2]; + } + else if (align[1] < 0) + { + // fill y + h = ch - item_pad[2] - item_pad[3]; + y = cy + item_pad[2]; + } + else + { + h = litem->minh - item_pad[2] - item_pad[3]; + y = cy + ((ch - h) * align[1]) + item_pad[2]; + } + + if (horiz) + { + if (h < pd->minh) h = pd->minh; + if (h > oh) h = oh; + } + else + { + if (w < pd->minw) w = pd->minw; + if (w > ow) w = ow; + } + + evas_object_geometry_set(litem->layout, (x + 0 - pd->pan.x), (y + 0 - pd->pan.y), w, h); + + litem->x = x; + litem->y = y; + order = eina_list_append(order, litem->layout); + +// fprintf(stderr, "x: %.2f y: %.2f w: %.2f h: %.2f old x: %.2f old y: %.2f old w: %.2f old h: %.2f\n" +// , (x + 0 - pd->pan.x), (y + 0 - pd->pan.y), (float)w, (float)h +// , (float)litem->x, (float)litem->y, (float)litem->w, (float)litem->h); fflush(stderr); +// printf("obj=%d currpos=%.2f moved to X=%.2f, Y=%.2f average_item_size %d\n", litem->index, cur_pos, x, y +// , eina_inarray_count(&pd->items.array) ? (/*horz*/ EINA_FALSE ? pd->realized.w : pd->realized.h) / eina_inarray_count(&pd->items.array) : AVERAGE_SIZE_INIT); + } + + efl_ui_focus_manager_calc_update_order(pd->manager, pd->obj, order); +} + +/* Internal EO APIs and hidden overrides */ + +#define EFL_UI_LIST_EXTRA_OPS \ + EFL_CANVAS_GROUP_ADD_DEL_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 new file mode 100644 index 0000000000..c753a45d63 --- /dev/null +++ b/src/lib/elementary/efl_ui_list.eo @@ -0,0 +1,94 @@ +struct Efl.Ui.List.Item_Event +{ + layout: Efl.Ui.Layout; + child: Efl.Model; + index: int; +} + +class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, Elm.Interface_Scrollable, + Elm.Interface.Atspi_Widget_Action, Efl.Access.Selection, + Efl.Ui.Clickable, Efl.Ui.Selectable) +{ + methods { + @property homogeneous { + get { + [[Get whether the homogeneous mode is enabled.]] + } + set { + [[Enable/disable homogeneous mode.]] + } + values { + homogeneous: bool; [[Assume the items within the genlist are of + the same height and width. Default is $false.]] + } + } + @property select_mode { + [[Listview select mode.]] + get {} + set {} + values { + mode: Elm.Object.Select_Mode(Elm.Object.Select_Mode.max); [[The select mode.]] + } + } + @property default_style { + values { + style: stringshare; + } + } + @property layout_factory { + [[Listview layout factory set.]] + set {} + values { + factory: Efl.Ui.Factory; [[The factory.]] + } + } + } + events { + item,realized : Efl.Ui.List.Item_Event; + item,unrealized : Efl.Ui.List.Item_Event; + item,focused : Efl.Ui.List.Item_Event; + item,unfocused : Efl.Ui.List.Item_Event; + item,highlighted : Efl.Ui.List.Item_Event; + item,unhighlighted : Efl.Ui.List.Item_Event; + item,selected : Efl.Ui.List.Item_Event; + item,unselected : Efl.Ui.List.Item_Event; + } + + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Gfx.position { set; } + Efl.Gfx.size { set; } + // Smart obj + Efl.Canvas.Group.group_member_add; + Efl.Canvas.Group.group_calculate; + + // Widget + Elm.Widget.theme_apply; +// Elm.Widget.focus_next_manager_is; +// Elm.Widget.focus_direction_manager_is; +// Elm.Widget.focus_register; +// Elm.Widget.focus_next; +// Elm.Widget.on_focus_update; +// Elm.Widget.activate; +// Elm.Widget.focused_item { get; } +// Elm.Widget.focused_object { get; } + Elm.Widget.focus_manager_create; + Elm.Widget.widget_event; + + //Efl.Ui.Layout.sizing_eval; + Efl.Ui.View.model { get; set; } + + Elm.Interface_Scrollable.region_bring_in; + Elm.Interface.Atspi_Accessible.children { get; } + Elm.Interface.Atspi_Widget_Action.elm_actions { get; } + Efl.Access.Selection.selected_children_count { get; } + Efl.Access.Selection.selected_child { get; } + Efl.Access.Selection.selected_child_deselect; + Efl.Access.Selection.child_select; + Efl.Access.Selection.child_deselect; + Efl.Access.Selection.is_child_selected; + Efl.Access.Selection.all_children_select; + Efl.Access.Selection.clear; + } +} diff --git a/src/lib/elementary/efl_ui_list_pan.eo b/src/lib/elementary/efl_ui_list_pan.eo new file mode 100644 index 0000000000..6a3db0d0b5 --- /dev/null +++ b/src/lib/elementary/efl_ui_list_pan.eo @@ -0,0 +1,15 @@ +class Efl.Ui.List.Pan (Elm.Pan) +{ + [[Elementary Efl_Ui_List pan class]] + implements { + Efl.Object.destructor; + Elm.Pan.content_size { get; } + Elm.Pan.pos { get; set; } + Elm.Pan.pos_min { get; } + Elm.Pan.pos_max { get; } + } + events { + item,focused; [[Called when item got focus]] + item,unfocused; [[Called when item lost focus]] + } +} diff --git a/src/lib/elementary/efl_ui_list_private.h b/src/lib/elementary/efl_ui_list_private.h new file mode 100644 index 0000000000..d7dd87de67 --- /dev/null +++ b/src/lib/elementary/efl_ui_list_private.h @@ -0,0 +1,131 @@ +#ifndef EFL_UI_LIST_PRIVATE_H +#define EFL_UI_LIST_PRIVATE_H + +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED +#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED +#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED + +#include <Elementary.h> +#include "elm_priv.h" + +typedef struct _Efl_Ui_List_Item Efl_Ui_List_Item; +typedef struct _Efl_Ui_List_Data Efl_Ui_List_Data; + +struct _Efl_Ui_List_Item +{ + Efl_Ui_List *list; + Efl_Model *model; + Efl_Ui_Layout *layout; + Efl_Future *future; + unsigned int index; + Evas_Coord x, y, minw, minh, w, h; + // double h, v, wx, wy; + double wx, wy; + Ecore_Timer *long_timer; + Eina_Bool selected: 1; + Eina_Bool down: 1; + Eina_Bool longpressed : 1; +}; + +typedef struct _Efl_Ui_List_Data Efl_Ui_List_Data; + +struct _Efl_Ui_List_Data +{ + Eo *obj; + Evas_Object *hit_rect; + Efl_Model *model; + + Efl_Orient orient; + + struct { + double h, v; + Eina_Bool scalable: 1; + } pad; + + struct { + double h, v; + } align; + + struct { + double x, y; + } weight; + + struct { + Evas_Coord w, h; + int start; + int slice; + } realized; + + struct { + Evas_Coord x, y, move_diff; + Evas_Object *obj; + } pan; + + Efl_Ui_Layout_Factory *factory; + Eina_List *selected_items; + struct { + Eina_Inarray array; + } items; + Eina_Stringshare *style; + Elm_Object_Select_Mode select_mode; + Elm_List_Mode mode; + + Efl_Ui_Focus_Manager *manager; + Evas_Coord minw, minh; + int /*average_item_size, avsom, */item_count; + Efl_Future *future; + struct { + int slice_start; + int slice; + } outstanding_slice; + + Eina_Bool homogeneous : 1; + Eina_Bool recalc : 1; + Eina_Bool on_hold : 1; +}; + +typedef struct _Efl_Ui_List_Pan_Data Efl_Ui_List_Pan_Data; + +struct _Efl_Ui_List_Pan_Data +{ + Eo *wobj; + Efl_Ui_List_Data *wpd; + Ecore_Job *resize_job; +}; + +typedef struct _Efl_Ui_List_Slice Efl_Ui_List_Slice; + +struct _Efl_Ui_List_Slice +{ + Efl_Ui_List_Data *pd; + int newstart, slicestart, newslice; +}; + + + +#define EFL_UI_LIST_DATA_GET(o, ptr) \ + Efl_Ui_List_Data * ptr = efl_data_scope_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)) \ + { \ + CRI("No widget data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return; \ + } + +#define EFL_UI_LIST_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ + EFL_UI_LIST_DATA_GET(o, ptr); \ + if (EINA_UNLIKELY(!ptr)) \ + { \ + CRI("No widget data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return val; \ + } + +#endif diff --git a/src/lib/elementary/elm_widget_layout.h b/src/lib/elementary/elm_widget_layout.h index ab4058fec7..6c4554d78c 100644 --- a/src/lib/elementary/elm_widget_layout.h +++ b/src/lib/elementary/elm_widget_layout.h @@ -53,7 +53,7 @@ typedef struct _Elm_Layout_Smart_Data Eina_List *subs; /**< List of Elm_Layout_Sub_Object_Data structs, to hold the actual sub objects such as text, content and the children of box and table. */ Eina_List *edje_signals; /**< The list of edje signal callbacks. */ Eina_List *parts_cursors; /**< The list of cursor names of layout parts. This is a list of Elm_Layout_Sub_Object_Cursor struct. */ - Eina_List *prop_connect; /**< The hash of properties connected to layout parts. */ + Eina_List *prop_connect; /**< The list of properties connected to layout parts. */ Eina_Hash *factories; /**< The hash with parts connected to factories. */ Efl_Model *model; /**< The model */ const char *klass; /**< 1st identifier of an edje object group which is used in theme_set. klass and group are used together. */ |