From e2fca6c454c182d4666c2f081697ed6f917ff645 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Wed, 9 Aug 2017 16:22:48 +0900 Subject: [PATCH] elm: Prevent style/theme set after finalize (EO) This is only for EO obviously. style_set and theme_set should only be called when the object is being created, not after. On-the-fly style changes are complex to handle and in most cases it should be easy to simply repopulate the object after creating a new one with a new style. There are only a few cases where style_set is used long after creation of an object, like changing how a label slides, or in the evas 3d map examples. Menu seems to change the hover style a lot, so rewriting it in pure EO would need some extra work, maybe. Ref T5307 Ref T5363 --- src/lib/elementary/efl_ui_layout.c | 6 ++++++ src/lib/elementary/elc_combobox.c | 17 +++++++++-------- src/lib/elementary/elm_widget.c | 15 +++++++++++++++ src/lib/elementary/elm_widget.eo | 2 +- src/lib/elementary/elm_widget.h | 9 +++++++++ 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/lib/elementary/efl_ui_layout.c b/src/lib/elementary/efl_ui_layout.c index ce6a49d..e2c7e14 100644 --- a/src/lib/elementary/efl_ui_layout.c +++ b/src/lib/elementary/efl_ui_layout.c @@ -900,6 +900,12 @@ _efl_ui_layout_theme_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *klass, con { ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); + if (!wd->legacy && efl_finalized_get(obj)) + { + ERR("Efl.Ui.Layout.theme can only be set before finalize!"); + return EFL_UI_THEME_APPLY_FAILED; + } + if (sd->file_set) sd->file_set = EINA_FALSE; eina_stringshare_replace(&(sd->klass), klass); eina_stringshare_replace(&(sd->group), group); diff --git a/src/lib/elementary/elc_combobox.c b/src/lib/elementary/elc_combobox.c index bd745c7..c8c0d87 100644 --- a/src/lib/elementary/elc_combobox.c +++ b/src/lib/elementary/elc_combobox.c @@ -4,6 +4,7 @@ #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED +#define ELM_WIDGET_PROTECTED #include #include "elm_priv.h" @@ -354,15 +355,15 @@ _elm_combobox_efl_object_constructor(Eo *obj, Elm_Combobox_Data *sd) //hover-parent sd->hover_parent = elm_object_top_widget_get(obj); + snprintf(buf, sizeof(buf), "combobox_vertical/%s", elm_widget_style_get(obj)); + //hover - sd->hover = efl_add(ELM_HOVER_CLASS, sd->hover_parent); + sd->hover = efl_add(ELM_HOVER_CLASS, sd->hover_parent, + elm_obj_widget_style_set(efl_added, buf)); evas_object_layer_set(sd->hover, EVAS_LAYER_MAX); efl_ui_mirrored_automatic_set(sd->hover, EINA_FALSE); elm_hover_target_set(sd->hover, obj); elm_widget_sub_object_add(obj, sd->hover); - snprintf(buf, sizeof(buf), "combobox_vertical/%s", - elm_widget_style_get(obj)); - elm_object_style_set(sd->hover, buf); efl_event_callback_add (sd->hover, EFL_UI_EVENT_CLICKED, _on_hover_clicked, obj); @@ -382,7 +383,8 @@ _elm_combobox_efl_object_constructor(Eo *obj, Elm_Combobox_Data *sd) elm_table_pack(sd->tbl, sd->spacer, 0, 0, 1, 1); // This is the genlist object that will take over the genlist call - sd->genlist = gl = efl_add(ELM_GENLIST_CLASS, obj); + sd->genlist = gl = efl_add(ELM_GENLIST_CLASS, obj, + elm_obj_widget_style_set(efl_added, buf)); elm_genlist_filter_set(gl, NULL); efl_ui_mirrored_automatic_set(gl, EINA_FALSE); efl_ui_mirrored_set(gl, efl_ui_mirrored_get(obj)); @@ -394,10 +396,10 @@ _elm_combobox_efl_object_constructor(Eo *obj, Elm_Combobox_Data *sd) elm_genlist_homogeneous_set(gl, EINA_TRUE); elm_genlist_mode_set(gl, ELM_LIST_COMPRESS); elm_table_pack(sd->tbl, gl, 0, 0, 1, 1); - elm_object_style_set(gl, buf); // This is the entry object that will take over the entry call - sd->entry = entry = efl_add(ELM_ENTRY_CLASS, obj); + sd->entry = entry = efl_add(ELM_ENTRY_CLASS, obj, + elm_obj_widget_style_set(efl_added, buf)); efl_ui_mirrored_automatic_set(entry, EINA_FALSE); efl_ui_mirrored_set(entry, efl_ui_mirrored_get(obj)); elm_scroller_policy_set(entry, ELM_SCROLLER_POLICY_OFF, @@ -409,7 +411,6 @@ _elm_combobox_efl_object_constructor(Eo *obj, Elm_Combobox_Data *sd) evas_object_show(entry); elm_object_part_content_set(obj, "elm.swallow.content", entry); - elm_object_style_set(entry, buf); efl_composite_attach(obj, gl); efl_composite_attach(obj, entry); diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c index b21436b..b0b515c 100644 --- a/src/lib/elementary/elm_widget.c +++ b/src/lib/elementary/elm_widget.c @@ -3931,6 +3931,12 @@ _elm_widget_theme_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd) EOLIAN static Efl_Ui_Theme_Apply _elm_widget_style_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *style) { + if (!sd->legacy && efl_finalized_get(obj)) + { + ERR("Efl.Ui.Widget.style can only be set before finalize!"); + return EFL_UI_THEME_APPLY_FAILED; + } + if (eina_stringshare_replace(&sd->style, style)) return elm_widget_theme(obj); @@ -6154,6 +6160,14 @@ _elm_widget_efl_object_destructor(Eo *obj, Elm_Widget_Smart_Data *sd) sd->on_destroy = EINA_FALSE; } +/* internal eo */ +static void +_elm_widget_legacy_ctor(Eo *obj, Elm_Widget_Smart_Data *sd) +{ + efl_canvas_object_legacy_ctor(efl_super(obj, MY_CLASS)); + sd->legacy = EINA_TRUE; +} + EOLIAN static Eina_Strbuf * _elm_widget_efl_object_debug_name_override(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, Eina_Strbuf *sb) { @@ -6570,6 +6584,7 @@ ELM_PART_TEXT_DEFAULT_GET(elm_widget, NULL) EFL_CANVAS_GROUP_ADD_DEL_OPS(elm_widget), \ ELM_PART_CONTENT_DEFAULT_OPS(elm_widget), \ ELM_PART_TEXT_DEFAULT_OPS(elm_widget), \ + EFL_OBJECT_OP_FUNC(efl_canvas_object_legacy_ctor, _elm_widget_legacy_ctor), \ EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _elm_widget_efl_object_dbg_info_get) #include "elm_widget_item.eo.c" diff --git a/src/lib/elementary/elm_widget.eo b/src/lib/elementary/elm_widget.eo index 5c369ba..59ab226 100644 --- a/src/lib/elementary/elm_widget.eo +++ b/src/lib/elementary/elm_widget.eo @@ -68,7 +68,7 @@ abstract Elm.Widget (Efl.Canvas.Group, Elm.Interface.Atspi_Accessible, The style can only be set before @Efl.Object.finalize, which means at construction time of the object (inside $efl_add in C). ]] - set { + set @protected { [[Can only be called during construction, before finalize.]] return: Efl.Ui.Theme.Apply(0); [[Whether the style was successfully applied or not, see diff --git a/src/lib/elementary/elm_widget.h b/src/lib/elementary/elm_widget.h index 8c7382f..86d5b6f 100644 --- a/src/lib/elementary/elm_widget.h +++ b/src/lib/elementary/elm_widget.h @@ -468,6 +468,7 @@ typedef struct _Elm_Widget_Smart_Data Eina_Bool on_create : 1; /**< This is true when the widget is on creation(general widget constructor). */ Eina_Bool on_destroy: 1; /**< This is true when the widget is on destruction(general widget destructor). */ Eina_Bool provider_lookup : 1; /**< This is true when efl_provider_find is currently walking the tree */ + Eina_Bool legacy : 1; /**< Widget was created with a legacy API, not efl_add() */ } Elm_Widget_Smart_Data; /** @@ -851,6 +852,14 @@ _elm_widget_sub_object_redirect_to_top(Evas_Object *obj, Evas_Object *sobj) return ret; } +static inline Eina_Bool +elm_widget_is_legacy(const Eo *obj) +{ + Elm_Widget_Smart_Data *sd = (Elm_Widget_Smart_Data *) + efl_data_scope_safe_get(obj, ELM_WIDGET_CLASS); + return sd ? sd->legacy : EINA_FALSE; +} + /* to be used by INTERNAL classes on Elementary, so that the widgets * parsing script skips it */ #define ELM_INTERNAL_SMART_SUBCLASS_NEW EVAS_SMART_SUBCLASS_NEW -- 2.7.4