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
This commit is contained in:
Jean-Philippe Andre 2017-08-09 16:22:48 +09:00
parent 5d1e959f92
commit e2fca6c454
5 changed files with 40 additions and 9 deletions

View File

@ -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);

View File

@ -4,6 +4,7 @@
#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
#define ELM_WIDGET_PROTECTED
#include <Elementary.h>
#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);

View File

@ -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"

View File

@ -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

View File

@ -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