summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-02-26 15:38:28 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-03-09 11:12:26 +0100
commita1addad60e1c9d9a32a6559460f23610932afc21 (patch)
treeb39ff1715e40f794960a9d81aba946aed01b0954
parentccbc27f24da1f6fd1494f478f36359aaf1502dc2 (diff)
efl_ui_widget: refactor sub_object handling
efl_ui_widget has a property called widget_parent. The setter for this function is called is exactly once, and this is within the constructor, to a value which is not even set to the actaul field parent_obj. Which shows, that in the sitation right now, the setter of the property is a bit disconnected and lags some real aspects. As we are heading towards eo-api stabilization we should beat some sense into this setter, as people using our classes might overwrite the setter and except calls to it, whenever the widget_parent is changed, and implementation as in elm_menu show that this might makes sense sometime. In order to achive this, the sub_object registering code of elm is adjusted a bit. sub_object_add/del is now used to differenciate between evas objects and efl.ui.widget objects as subobject. In case of a widget, the widget_parent of this object is set, most of the widget specific code is then executed in the actaul setter. In case of an evas object, the parent reference is added. In the end both end up in the subobject children list. The later is also a requirement for widget_parent_set to be successfull. ref T7553 Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Differential Revision: https://phab.enlightenment.org/D8031
-rw-r--r--src/lib/elementary/efl_ui_widget.c188
1 files changed, 89 insertions, 99 deletions
diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c
index 25462ceb02..ed959eb479 100644
--- a/src/lib/elementary/efl_ui_widget.c
+++ b/src/lib/elementary/efl_ui_widget.c
@@ -1151,10 +1151,6 @@ elm_widget_focus_region_show(Eo *obj)
1151 } 1151 }
1152} 1152}
1153 1153
1154EOLIAN static void
1155_efl_ui_widget_widget_parent_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *parent EINA_UNUSED)
1156{
1157}
1158 1154
1159EAPI Eina_Bool 1155EAPI Eina_Bool
1160elm_widget_api_check(int ver) 1156elm_widget_api_check(int ver)
@@ -1378,74 +1374,27 @@ elm_widget_sub_object_parent_add(Evas_Object *sobj)
1378 return elm_widget_sub_object_add(parent, sobj); 1374 return elm_widget_sub_object_add(parent, sobj);
1379} 1375}
1380 1376
1381/* 1377EOLIAN static void
1382 * @internal 1378_efl_ui_widget_widget_parent_set(Eo *obj, Elm_Widget_Smart_Data *pd, Efl_Ui_Widget *parent)
1383 *
1384 * Add sobj to obj's sub object.
1385 *
1386 * What does elementary sub object mean? This is unique in elementary, it
1387 * handles overall elementary policies between parent and sub objects.
1388 * focus, access, deletion, theme, scale, mirror, scrollable child get,
1389 * translate, name find, display mode set, orientation set, tree dump
1390 * AUTOMATICALLY.
1391 *
1392 * @see elm_widget_sub_object_parent_add()
1393 */
1394EOLIAN static Eina_Bool
1395_efl_ui_widget_widget_sub_object_add(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1396{ 1379{
1397 Eina_Bool mirrored, pmirrored = efl_ui_mirrored_get(obj); 1380 Eina_Bool mirrored, pmirrored = efl_ui_mirrored_get(obj);
1398 Elm_Widget_Smart_Data *sdc = NULL; 1381 Efl_Ui_Widget *old_parent;
1399 1382 //check if we are in the subobject list of parents
1400 EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE); 1383 if (parent)
1401
1402 if (_elm_widget_is(sobj))
1403 sdc = efl_data_scope_get(sobj, MY_CLASS);
1404
1405 if (sobj == sd->parent_obj)
1406 { 1384 {
1407 /* in this case, sobj must be an elm widget, or something 1385 ELM_WIDGET_DATA_GET_OR_RETURN(parent, ppd);
1408 * very wrong is happening */ 1386 EINA_SAFETY_ON_FALSE_RETURN(eina_list_data_find(ppd->subobjs, obj));
1409 if (!sdc) return EINA_FALSE;
1410
1411 if (!elm_widget_sub_object_del(sobj, obj)) return EINA_FALSE;
1412 WRN("You passed a parent object of obj = %p as the sub object = %p!",
1413 obj, sobj);
1414 } 1387 }
1415 1388
1416 if (sdc) 1389 old_parent = pd->parent_obj;
1417 { 1390 pd->parent_obj = parent;
1418 if (sdc->parent_obj == obj) goto end;
1419 if (sdc->parent_obj)
1420 {
1421 if (!elm_widget_sub_object_del(sdc->parent_obj, sobj))
1422 return EINA_FALSE;
1423 }
1424 sdc->parent_obj = obj;
1425 1391
1426 _full_eval(sobj, sdc); 1392 // now lets sync up all states
1427 efl_ui_widget_disabled_set(sobj, efl_ui_widget_disabled_get(obj));
1428 1393
1429 _elm_widget_top_win_focused_set(sobj, sd->top_win_focused); 1394 if (pd->parent_obj)
1430 }
1431 else
1432 {
1433 void *data = evas_object_data_get(sobj, "elm-parent");
1434
1435 if (data)
1436 {
1437 if (data == obj) goto end;
1438 if (!elm_widget_sub_object_del(data, sobj)) return EINA_FALSE;
1439 }
1440 }
1441 sd->subobjs = eina_list_append(sd->subobjs, sobj);
1442 evas_object_data_set(sobj, "elm-parent", obj);
1443
1444 _callbacks_add(sobj, obj);
1445 if (sdc)
1446 { 1395 {
1447 /* NOTE: In the following two lines, 'sobj' is correct. Do not change it. 1396 /* NOTE: In the following two lines, 'sobj' is correct. Do not change it.
1448 * Due to elementary's scale policy, scale and pscale can be different in 1397 * Due to elementary's scale policy, scale and pscale can be different in
1449 * some cases. This happens when sobj's previous parent and new parent have 1398 * some cases. This happens when sobj's previous parent and new parent have
1450 * different scale value. 1399 * different scale value.
1451 * For example, if sobj's previous parent's scale is 5 and new parent's scale 1400 * For example, if sobj's previous parent's scale is 5 and new parent's scale
@@ -1453,33 +1402,85 @@ _efl_ui_widget_widget_sub_object_add(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Ob
1453 * need to reset sobj's scale to 5. 1402 * need to reset sobj's scale to 5.
1454 * Note that each widget's scale is 0 by default. 1403 * Note that each widget's scale is 0 by default.
1455 */ 1404 */
1456 double scale, pscale = efl_gfx_entity_scale_get(sobj); 1405 double scale, pscale = efl_gfx_entity_scale_get(obj);
1457 Elm_Theme *th, *pth = elm_widget_theme_get(sobj); 1406 Elm_Theme *th, *pth = elm_widget_theme_get(obj);
1458 1407
1459 scale = efl_gfx_entity_scale_get(sobj); 1408 scale = efl_gfx_entity_scale_get(obj);
1460 th = elm_widget_theme_get(sobj); 1409 th = elm_widget_theme_get(obj);
1461 mirrored = efl_ui_mirrored_get(sobj); 1410 mirrored = efl_ui_mirrored_get(obj);
1462 1411
1463 if (!sdc->on_create) 1412 if (!pd->on_create)
1464 { 1413 {
1465 if ((scale != pscale) || (th != pth) || (pmirrored != mirrored)) 1414 if ((scale != pscale) || (th != pth) || (pmirrored != mirrored))
1466 elm_widget_theme(sobj); 1415 elm_widget_theme(obj);
1467 } 1416 }
1417 if (_is_focused(obj)) _parents_focus(parent);
1418 elm_widget_display_mode_set(obj, evas_object_size_hint_display_mode_get(parent));
1419 elm_widget_disabled_set(obj, efl_ui_widget_disabled_get(parent));
1420 _elm_widget_top_win_focused_set(obj, _elm_widget_top_win_focused_get(parent));
1421 }
1468 1422
1469 if (_is_focused(sobj)) _parents_focus(obj); 1423 _full_eval(obj, pd);
1470 1424
1471 elm_widget_display_mode_set(sobj, 1425 if (old_parent && _elm_config->atspi_mode)
1472 evas_object_size_hint_display_mode_get(obj)); 1426 {
1473 if (_elm_config->atspi_mode && !sd->on_create) 1427 Efl_Access_Object *aparent;
1474 { 1428 aparent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
1475 Efl_Access_Object *aparent; 1429 if (aparent)
1476 aparent = efl_provider_find(efl_parent_get(sobj), EFL_ACCESS_OBJECT_MIXIN); 1430 efl_access_children_changed_del_signal_emit(aparent, obj);
1477 if (aparent) 1431 }
1478 efl_access_children_changed_added_signal_emit(aparent, sobj); 1432
1479 } 1433 if (pd->parent_obj && _elm_config->atspi_mode && efl_finalized_get(parent))
1434 {
1435 Efl_Access_Object *aparent;
1436 aparent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
1437 if (aparent)
1438 efl_access_children_changed_added_signal_emit(aparent, obj);
1480 } 1439 }
1440}
1441
1442static void
1443_widget_add_sub(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1444{
1445 sd->subobjs = eina_list_append(sd->subobjs, sobj);
1446 evas_object_data_set(sobj, "elm-parent", obj);
1447 _callbacks_add(sobj, obj);
1448}
1449
1450static void
1451_widget_del_sub(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1452{
1453 sd->subobjs = eina_list_remove(sd->subobjs, sobj);
1454 evas_object_data_del(sobj, "elm-parent");
1455 _callbacks_del(sobj, obj);
1456}
1457
1458EOLIAN static Eina_Bool
1459_efl_ui_widget_widget_sub_object_add(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1460{
1461 Efl_Ui_Widget *parent;
1462
1463 //first make sure that we unregister the sobj from the parent
1464 if (elm_widget_is(sobj))
1465 parent = efl_ui_widget_parent_get(sobj);
1466 else
1467 parent = evas_object_data_get(sobj, "elm-parent");
1468 if (parent == obj) return EINA_TRUE;
1469 if (parent)
1470 {
1471 if (!efl_ui_widget_sub_object_del(parent, sobj))
1472 return EINA_FALSE;
1473 }
1474
1475 //sobj does not have a parent here
1476 //first add it to our own children list
1477 _widget_add_sub(obj, sd, sobj);
1478
1479 //and if it is a widget, please set the correct parent on the widget itself
1480 //the parent set method will take care of the property syncing etc.
1481 if (elm_widget_is(sobj))
1482 efl_ui_widget_parent_set(sobj, obj);
1481 1483
1482end:
1483 return EINA_TRUE; 1484 return EINA_TRUE;
1484} 1485}
1485 1486
@@ -1519,25 +1520,13 @@ _efl_ui_widget_widget_sub_object_del(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Ob
1519 elm_widget_tree_unfocusable_set(sobj, EINA_TRUE); 1520 elm_widget_tree_unfocusable_set(sobj, EINA_TRUE);
1520 elm_widget_tree_unfocusable_set(sobj, EINA_FALSE); 1521 elm_widget_tree_unfocusable_set(sobj, EINA_FALSE);
1521 } 1522 }
1522 if (_elm_config->atspi_mode && !sd->on_destroy)
1523 {
1524 Efl_Access_Object *aparent;
1525 aparent = efl_provider_find(efl_parent_get(sobj), EFL_ACCESS_OBJECT_MIXIN);
1526 if (aparent)
1527 efl_access_children_changed_del_signal_emit(aparent, sobj);
1528 }
1529 1523
1530 ELM_WIDGET_DATA_GET(sobj, sdc); 1524 efl_ui_widget_parent_set(sobj, NULL);
1531 sdc->parent_obj = NULL;
1532
1533 _full_eval(sobj, sdc);
1534 } 1525 }
1535 1526
1536 if (sd->resize_obj == sobj) sd->resize_obj = NULL; 1527 if (sd->resize_obj == sobj) sd->resize_obj = NULL;
1537 1528
1538 sd->subobjs = eina_list_remove(sd->subobjs, sobj); 1529 _widget_del_sub(obj, sd, sobj);
1539
1540 _callbacks_del(sobj, obj);
1541 1530
1542 return EINA_TRUE; 1531 return EINA_TRUE;
1543} 1532}
@@ -5023,16 +5012,17 @@ elm_widget_tree_dot_dump(const Evas_Object *top,
5023EOLIAN static Eo * 5012EOLIAN static Eo *
5024_efl_ui_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED) 5013_efl_ui_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
5025{ 5014{
5026 Eo *parent = NULL;
5027
5028 sd->on_create = EINA_TRUE; 5015 sd->on_create = EINA_TRUE;
5029 _efl_ui_focus_event_redirector(obj, obj); 5016 _efl_ui_focus_event_redirector(obj, obj);
5030 efl_canvas_group_clipped_set(obj, EINA_FALSE); 5017 efl_canvas_group_clipped_set(obj, EINA_FALSE);
5031 obj = efl_constructor(efl_super(obj, MY_CLASS)); 5018 obj = efl_constructor(efl_super(obj, MY_CLASS));
5032 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY); 5019 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
5033 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks); 5020 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
5034 parent = efl_parent_get(obj); 5021 if (!efl_isa(obj, EFL_UI_WIN_CLASS))
5035 efl_ui_widget_parent_set(obj, parent); 5022 {
5023 efl_ui_widget_sub_object_add(efl_parent_get(obj), obj);
5024 }
5025
5036 sd->on_create = EINA_FALSE; 5026 sd->on_create = EINA_FALSE;
5037 5027
5038 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_UNKNOWN); 5028 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_UNKNOWN);