efl_ui_widget: reintroduce legacy behaviour
authorMarcel Hollerbach <mail@marcel-hollerbach.de>
Sun, 24 Mar 2019 17:58:50 +0000 (18:58 +0100)
committerJunsuChoi <jsuya.choi@samsung.com>
Tue, 2 Apr 2019 04:21:10 +0000 (13:21 +0900)
before the refactoring of the disabled property, there was no way to
enable a widget which has a disabled tree. This here however enables
this to work again like this. The user will be told with an error
message. The integraty of the property is maintained accross reparents.

Reviewed-by: Jaehyun Cho <jae_hyun.cho@samsung.com>
Differential Revision: https://phab.enlightenment.org/D8459

src/lib/elementary/efl_ui_widget.c
src/tests/elementary/efl_ui_test_widget.c

index c40fbd3..025b78b 100644 (file)
@@ -1489,6 +1489,35 @@ elm_widget_sub_object_parent_add(Evas_Object *sobj)
    return elm_widget_sub_object_add(parent, sobj);
 }
 
+static int
+_disabled_counter_get(Eo *widget)
+{
+   ELM_WIDGET_DATA_GET_OR_RETURN(widget, pd, -1);
+
+   return pd->disabled;
+}
+
+static void
+_mirror_disabled_state(Eo *obj, Elm_Widget_Smart_Data *pd, int disabled_delta)
+{
+   pd->disabled = (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0) + disabled_delta;
+
+   //we should not call disabled_set when things are invalidated
+   //otherwise we will unleashe an amount of errors in efl_ui_layout
+   if (efl_invalidated_get(obj)) return;
+
+   if (pd->disabled > 0)
+     {
+        pd->disabled --;
+        efl_ui_widget_disabled_set(obj, EINA_TRUE);
+     }
+   else
+     {
+        pd->disabled ++;
+        efl_ui_widget_disabled_set(obj, EINA_FALSE);
+     }
+}
+
 EOLIAN static void
 _efl_ui_widget_widget_parent_set(Eo *obj, Elm_Widget_Smart_Data *pd, Efl_Ui_Widget *parent)
 {
@@ -1512,6 +1541,7 @@ _efl_ui_widget_widget_parent_set(Eo *obj, Elm_Widget_Smart_Data *pd, Efl_Ui_Widg
    double scale, prev_scale = efl_gfx_entity_scale_get(obj);
    Elm_Theme *th, *prev_th = elm_widget_theme_get(obj);
    Eina_Bool mirrored, pmirrored = efl_ui_mirrored_get(parent);
+   int disabled_delta = pd->disabled - (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0);
 
    old_parent = pd->parent_obj;
    pd->parent_obj = parent;
@@ -1531,10 +1561,9 @@ _efl_ui_widget_widget_parent_set(Eo *obj, Elm_Widget_Smart_Data *pd, Efl_Ui_Widg
           }
         if (_is_focused(obj)) _parents_focus(parent);
         elm_widget_display_mode_set(obj, evas_object_size_hint_display_mode_get(parent));
-        elm_widget_disabled_set(obj, efl_ui_widget_disabled_get(parent));
         _elm_widget_top_win_focused_set(obj, _elm_widget_top_win_focused_get(parent));
      }
-
+   _mirror_disabled_state(obj, pd, disabled_delta);
    _full_eval(obj, pd);
 
    if (old_parent && _elm_config->atspi_mode)
@@ -2632,11 +2661,20 @@ _efl_ui_widget_disabled_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd, Eina
 {
    Efl_Ui_Widget *subs;
    Eina_List *n;
+   int distance, parent_counter = (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0);
 
    if (disabled)
      pd->disabled ++;
    else
-     pd->disabled = MAX(pd->disabled - 1 ,0);
+     pd->disabled --;
+
+   distance = pd->disabled - parent_counter;
+
+   if ((distance < 0) || (distance > 1))
+     {
+        distance = MAX(MIN(disabled, 1), 0);
+        pd->disabled = parent_counter + distance;
+     }
 
    EINA_LIST_FOREACH(pd->subobjs, n, subs)
      {
index bf75b0e..aa99299 100644 (file)
@@ -285,6 +285,42 @@ EFL_START_TEST(efl_ui_test_widget_disabled_parent)
 }
 EFL_END_TEST
 
+EFL_START_TEST(efl_ui_test_widget_disabled_behaviour)
+{
+   Efl_Ui_Win *win, *w1, *w2, *t;
+
+   win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+                 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
+                 efl_text_set(efl_added, "Hello World"));
+   //first check the initial state
+   w1 = efl_add(efl_ui_widget_realized_class_get(), win);
+   efl_ui_widget_disabled_set(w1, EINA_TRUE);
+   w2 = efl_add(efl_ui_widget_realized_class_get(), win);
+   efl_ui_widget_disabled_set(w2, EINA_FALSE);
+
+
+   t = efl_add(efl_ui_widget_realized_class_get(), win);
+   efl_ui_widget_sub_object_add(w1, t);
+   //check that we never enable something under disabled parent
+   DISABLE_ABORT_ON_CRITICAL_START;
+   efl_ui_widget_disabled_set(t, EINA_FALSE);
+   DISABLE_ABORT_ON_CRITICAL_END;
+   ck_assert_int_eq(efl_ui_widget_disabled_get(t), EINA_TRUE);
+   efl_del(t);
+
+   t = efl_add(efl_ui_widget_realized_class_get(), win);
+   efl_ui_widget_sub_object_add(w1, t);
+   //check that we can disable something with a disabled tree
+   efl_ui_widget_disabled_set(t, EINA_TRUE);
+   ck_assert_int_eq(efl_ui_widget_disabled_get(t), EINA_TRUE);
+   efl_ui_widget_sub_object_add(w2, t);
+   ck_assert_int_eq(efl_ui_widget_disabled_get(t), EINA_TRUE);
+   efl_del(t);
+
+   efl_del(win);
+}
+EFL_END_TEST
+
 static int tree_abort;
 static int tree_abort_level;
 
@@ -316,4 +352,5 @@ void efl_ui_test_widget(TCase *tc)
    tcase_add_test(tc, efl_ui_test_widget_sub_object_theme_sync);
    tcase_add_test(tc, efl_ui_test_widget_parent_relation);
    tcase_add_test(tc, efl_ui_test_widget_disabled_parent);
+   tcase_add_test(tc, efl_ui_test_widget_disabled_behaviour);
 }