diff --git a/src/lib/elementary/efl_ui_layout.c b/src/lib/elementary/efl_ui_layout.c index ce0ccec79b..5dd2c3d1a8 100644 --- a/src/lib/elementary/efl_ui_layout.c +++ b/src/lib/elementary/efl_ui_layout.c @@ -2394,10 +2394,15 @@ _efl_ui_layout_base_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Data *sd) EOLIAN static Efl_Object* _efl_ui_layout_base_efl_object_finalize(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED) { - Eo *eo; + Eo *eo, *win; ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); eo = efl_finalize(efl_super(obj, MY_CLASS)); efl_ui_widget_theme_apply(eo); + + win = efl_ui_widget_top_get(obj); + if (efl_isa(win, EFL_UI_WIN_CLASS)) + efl_ui_layout_theme_rotation_apply(obj, efl_ui_win_rotation_get(win)); + if (efl_file_get(wd->resize_obj) || efl_file_mmap_get(wd->resize_obj)) efl_file_load(wd->resize_obj); @@ -2582,6 +2587,35 @@ _efl_ui_layout_part_bg_efl_object_finalize(Eo *obj, void *_pd EINA_UNUSED) return obj; } +EOLIAN static void +_efl_ui_layout_base_automatic_theme_rotation_set(Eo *obj, Efl_Ui_Layout_Data *pd, Eina_Bool automatic) +{ + if (pd->automatic_orientation_apply == automatic) return; + pd->automatic_orientation_apply = automatic; + + efl_ui_layout_theme_rotation_apply(obj, efl_ui_win_rotation_get(efl_ui_widget_top_get(obj))); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_base_automatic_theme_rotation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd) +{ + return pd->automatic_orientation_apply; +} + +EOLIAN static void +_efl_ui_layout_base_theme_rotation_apply(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, Efl_Orient orientation) +{ + char prefix[4], buf[128]; + + if (elm_widget_is_legacy(obj)) + snprintf(prefix, sizeof(prefix), "elm"); + else + snprintf(prefix, sizeof(prefix), "efl"); + snprintf(buf, sizeof(buf), "%s,state,orient,%d", prefix, (int)orientation); + efl_layout_signal_emit(obj, buf, prefix); +} + + /* Efl.Ui.Layout_Part_Xxx includes */ #include "efl_ui_layout_part.eo.c" #include "efl_ui_layout_part_content.eo.c" diff --git a/src/lib/elementary/efl_ui_layout_base.eo b/src/lib/elementary/efl_ui_layout_base.eo index e2384c06e0..a024feefd6 100644 --- a/src/lib/elementary/efl_ui_layout_base.eo +++ b/src/lib/elementary/efl_ui_layout_base.eo @@ -1,4 +1,5 @@ import efl_ui; +import efl_orientation; abstract @beta Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container, Efl.Ui.View, Efl.Ui.Property_Bind, Efl.Ui.Factory_Bind, @@ -45,6 +46,19 @@ abstract @beta Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container style: string("default"); [[The style to use, eg "default".]] } } + @property automatic_theme_rotation { + [[This flag tells if this object will automatically mirror the rotation changes of the window to this object. + ]] + values { + automatic : bool; [[$true to mirror orientation changes to the theme $false otherwise]] + } + } + theme_rotation_apply { + [[Apply a new rotation value to this object.]] + params { + orientation : Efl.Orient; [[The new rotation value.]] + } + } } implements { class.constructor; diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c index 3c6b429dfe..edff7f479b 100644 --- a/src/lib/elementary/efl_ui_widget.c +++ b/src/lib/elementary/efl_ui_widget.c @@ -1498,11 +1498,6 @@ _efl_ui_widget_widget_sub_object_add(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Ob _full_eval(sobj, sdc); - if (!sdc->on_create) - efl_ui_widget_on_orientation_update(sobj, sd->orient_mode); - else - sdc->orient_mode = sd->orient_mode; - if (!sdc->on_create) { if (!sdc->disabled && (elm_widget_disabled_get(obj))) @@ -3158,22 +3153,6 @@ elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wnam return EFL_UI_THEME_APPLY_RESULT_FAIL; } - if (sd->orient_mode != -1) - { - char buf[128]; - - if (elm_widget_is_legacy(obj)) - { - snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode); - elm_widget_signal_emit(obj, buf, "elm"); - } - else - { - snprintf(buf, sizeof(buf), "efl,state,orient,%d", sd->orient_mode); - elm_widget_signal_emit(obj, buf, "efl"); - } - } - return ret; } @@ -3609,60 +3588,6 @@ elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode) } } -EOLIAN static void -_efl_ui_widget_orientation_mode_set(Eo *obj, Elm_Widget_Smart_Data *sd, Efl_Ui_Widget_Orientation_Mode mode) -{ - int rotation = -1; - - if (mode != EFL_UI_WIDGET_ORIENTATION_MODE_DISABLED) - { - //Get current orient mode from it's parent otherwise, 0. - sd->orient_mode = 0; - ELM_WIDGET_DATA_GET(sd->parent_obj, sd_parent); - if (!sd_parent) rotation = 0; - else rotation = sd_parent->orient_mode; - } - efl_ui_widget_on_orientation_update(obj, rotation); -} - -EOLIAN static Efl_Ui_Widget_Orientation_Mode -_efl_ui_widget_orientation_mode_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd) -{ - if (sd->orient_mode == -1) return EFL_UI_WIDGET_ORIENTATION_MODE_DISABLED; - else return EFL_UI_WIDGET_ORIENTATION_MODE_DEFAULT; -} - -EOLIAN static void -_efl_ui_widget_on_orientation_update(Eo *obj, Elm_Widget_Smart_Data *sd, int orient_mode) -{ - Evas_Object *child; - Eina_List *l; - - sd->orient_mode = orient_mode; - - EINA_LIST_FOREACH (sd->subobjs, l, child) - { - if (elm_widget_is(child)) - efl_ui_widget_on_orientation_update(child, orient_mode); - } - - if (orient_mode != -1) - { - char buf[128]; - - if (elm_widget_is_legacy(obj)) - { - snprintf(buf, sizeof(buf), "elm,state,orient,%d", orient_mode); - elm_widget_signal_emit(obj, buf, "elm"); - } - else - { - snprintf(buf, sizeof(buf), "efl,state,orient,%d", orient_mode); - elm_widget_signal_emit(obj, buf, "efl"); - } - } -} - /** * @internal * diff --git a/src/lib/elementary/efl_ui_widget.eo b/src/lib/elementary/efl_ui_widget.eo index 09e2303f11..6fb8a03c38 100644 --- a/src/lib/elementary/efl_ui_widget.eo +++ b/src/lib/elementary/efl_ui_widget.eo @@ -312,48 +312,6 @@ abstract @beta Efl.Ui.Widget extends Efl.Canvas.Group implements Efl.Access.Obje return: bool; [[Indicates if the operation succeeded.]] legacy: elm_widget_sub_object_del; } - @property orientation_mode { - [[Whether the widget's automatic orientation is enabled or not. - - Orientation mode is used for widgets to change their style or send - signals based on the canvas rotation (i.e. the window orientation). - If the orientation mode is enabled, the widget will emit signals - such as "elm,state,orient,N" where $N is one of 0, 90, 180, 270, - depending on the window orientation. Such signals may be handled by - the theme in order to provide a different look for the widget based - on the canvas orientation. - - By default orientation mode is enabled. - - See also @.on_orientation_update. - ]] - values { - mode: Efl.Ui.Widget_Orientation_Mode(Efl.Ui.Widget_Orientation_Mode.default); - [[How window orientation should affect this widget.]] - } - } - on_orientation_update @protected { - [[Virtual function handling canvas orientation changes. - - This method will be called recursively from the top widget (the - window) to all the children objects whenever the window rotation - is changed. The given $rotation will be one of 0, 90, 180, 270 or - the special value -1 if @.orientation_mode is $disabled. - - If @.orientation_mode is $default, the widget implementation will - emit the signal "elm,state,orient,$R" will be emitted (where $R is - the rotation angle in degrees). - - Note: This function may be called even if the orientation has not - actually changed, like when a widget needs to be reconfigured. - - See also @.orientation_mode. - ]] - params { - rotation: int; [[Orientation in degrees: 0, 90, 180, 270 or -1 if - @.orientation_mode is $disabled.]] - } - } on_disabled_update @protected { [[Virtual function called when the widget becomes disabled. diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c index 472e1bf6ef..f3086dbc3f 100644 --- a/src/lib/elementary/efl_ui_win.c +++ b/src/lib/elementary/efl_ui_win.c @@ -35,6 +35,7 @@ #include "efl_ui_win_legacy.eo.h" #include "efl_ui_win_socket_legacy.eo.h" #include "efl_ui_win_inlined_legacy.eo.h" +#include "efl_ui_widget_common.h" #define MY_CLASS EFL_UI_WIN_CLASS #define MY_CLASS_NAME "Efl.Ui.Win" @@ -212,6 +213,7 @@ struct _Efl_Ui_Win_Data int norender; int modal_count; int response; + int rotation; Eina_Bool req_wh : 1; Eina_Bool req_xy : 1; @@ -1558,6 +1560,93 @@ _elm_win_frame_obj_update(Efl_Ui_Win_Data *sd, Eina_Bool force) TRAP(sd, resize, w, h); } +static int +_win_rotation_degree_check(int rotation) +{ + if ((rotation > 360) || (rotation < 0)) + { + WRN("Rotation degree should be 0 ~ 360 (passed degree: %d)", rotation); + rotation %= 360; + if (rotation < 0) rotation += 360; + } + return rotation; +} + +/* + * This API resizes the internal window(ex: X window) and evas_output. + * But this does not resize the elm window object and its contents. + */ +static void +_win_rotate(Evas_Object *obj, Efl_Ui_Win_Data *sd, int rotation, Eina_Bool resize) +{ + rotation = _win_rotation_degree_check(rotation); + if (sd->rot == rotation) return; + sd->rot = rotation; + if (resize) TRAP(sd, rotation_with_resize_set, rotation); + else TRAP(sd, rotation_set, rotation); + efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(-1, -1)); + efl_gfx_hint_size_max_set(obj, EINA_SIZE2D(-1, -1)); + _elm_win_resize_objects_eval(obj, EINA_FALSE); +#ifdef HAVE_ELEMENTARY_X + _elm_win_xwin_update(sd); +#endif + _elm_win_frame_obj_update(sd, 0); + efl_event_callback_legacy_call + (obj, EFL_UI_WIN_EVENT_ROTATION_CHANGED, NULL); + if (_elm_config->atspi_mode) + { + Evas_Coord x = 0, y = 0, width = 0, height = 0; + elm_win_screen_size_get(obj, &x, &y, &width, &height); + if ((sd->rot == 0) || (sd->rot == 180)) + { + efl_access_bounds_changed_signal_emit(obj, x, y, width, height); + } + else + { + efl_access_bounds_changed_signal_emit(obj, x, y, height, width); + } + } +} + +EOLIAN static void +_efl_ui_win_win_rotation_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd, Efl_Orient rotation) +{ + Efl_Ui_Widget *widget; + Eina_Iterator *it; + int rot = rotation %360; + + if (pd->rot == rot) return; + + _win_rotate(obj, pd, rot, EINA_FALSE); + + it = efl_ui_widget_tree_widget_iterator(obj); + EINA_ITERATOR_FOREACH(it, widget) + { + if (!efl_isa(widget, EFL_UI_LAYOUT_CLASS)) continue; + + if (efl_ui_layout_automatic_theme_rotation_get(widget)) + efl_ui_layout_theme_rotation_apply(widget, rot); + } +} + +EOLIAN static Efl_Orient +_efl_ui_win_win_rotation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *pd) +{ + return pd->rotation; +} + +EAPI void +elm_win_rotation_set(Evas_Object *obj, int rotation) +{ + efl_ui_win_rotation_set(obj, rotation); +} + +EAPI int +elm_win_rotation_get(const Evas_Object *obj) +{ + return efl_ui_win_rotation_get(obj); +} + static void _elm_win_state_change(Ecore_Evas *ee) { @@ -1613,7 +1702,6 @@ _elm_win_state_change(Ecore_Evas *ee) { if (sd->rot != ecore_evas_rotation_get(sd->ee)) { - sd->rot = ecore_evas_rotation_get(sd->ee); ch_wm_rotation = EINA_TRUE; } } @@ -1691,31 +1779,10 @@ _elm_win_state_change(Ecore_Evas *ee) } if (ch_wm_rotation) { - efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(-1, -1)); - efl_gfx_hint_size_max_set(obj, EINA_SIZE2D(-1, -1)); -#ifdef HAVE_ELEMENTARY_X - ELM_WIN_DATA_ALIVE_CHECK(obj, sd); - _elm_win_xwin_update(sd); -#endif - ELM_WIN_DATA_ALIVE_CHECK(obj, sd); - efl_ui_widget_on_orientation_update(obj, sd->rot); - efl_event_callback_legacy_call - (obj, EFL_UI_WIN_EVENT_ROTATION_CHANGED, NULL); + efl_ui_win_rotation_set(obj, ecore_evas_rotation_get(sd->ee)); + efl_event_callback_legacy_call (obj, EFL_UI_WIN_EVENT_WM_ROTATION_CHANGED, NULL); - if (_elm_config->atspi_mode) - { - Evas_Coord x = 0, y = 0, width = 0, height = 0; - elm_win_screen_size_get(obj, &x, &y, &width, &height); - if ((sd->rot == 0) || (sd->rot == 180)) - { - efl_access_bounds_changed_signal_emit(obj, x, y, width, height); - } - else - { - efl_access_bounds_changed_signal_emit(obj, x, y, height, width); - } - } } } @@ -6581,55 +6648,6 @@ elm_win_render(Evas_Object *obj) ecore_evas_manual_render(sd->ee); } -static int -_win_rotation_degree_check(int rotation) -{ - if ((rotation > 360) || (rotation < 0)) - { - WRN("Rotation degree should be 0 ~ 360 (passed degree: %d)", rotation); - rotation %= 360; - if (rotation < 0) rotation += 360; - } - return rotation; -} - -/* - * This API resizes the internal window(ex: X window) and evas_output. - * But this does not resize the elm window object and its contents. - */ -static void -_win_rotate(Evas_Object *obj, Efl_Ui_Win_Data *sd, int rotation, Eina_Bool resize) -{ - rotation = _win_rotation_degree_check(rotation); - if (sd->rot == rotation) return; - sd->rot = rotation; - if (resize) TRAP(sd, rotation_with_resize_set, rotation); - else TRAP(sd, rotation_set, rotation); - efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(-1, -1)); - efl_gfx_hint_size_max_set(obj, EINA_SIZE2D(-1, -1)); - _elm_win_resize_objects_eval(obj, EINA_FALSE); -#ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); -#endif - _elm_win_frame_obj_update(sd, 0); - efl_ui_widget_on_orientation_update(obj, rotation); - efl_event_callback_legacy_call - (obj, EFL_UI_WIN_EVENT_ROTATION_CHANGED, NULL); - if (_elm_config->atspi_mode) - { - Evas_Coord x = 0, y = 0, width = 0, height = 0; - elm_win_screen_size_get(obj, &x, &y, &width, &height); - if ((sd->rot == 0) || (sd->rot == 180)) - { - efl_access_bounds_changed_signal_emit(obj, x, y, width, height); - } - else - { - efl_access_bounds_changed_signal_emit(obj, x, y, height, width); - } - } -} - EOLIAN static void _efl_ui_win_wm_available_rotations_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, Eina_Bool allow_0, Eina_Bool allow_90, @@ -8224,15 +8242,6 @@ elm_win_wm_rotation_manual_rotation_done(Evas_Object *obj) ecore_evas_wm_rotation_manual_rotation_done(sd->ee); } -EAPI void -elm_win_rotation_set(Evas_Object *obj, int rotation) -{ - Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS); - if (!sd) return; - - _win_rotate(obj, sd, rotation, EINA_FALSE); -} - /* * This API does not resize the internal window (ex: X window). * But this resizes evas_output, elm window, and its contents. @@ -8246,15 +8255,6 @@ elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation) _win_rotate(obj, sd, rotation, EINA_TRUE); } -EAPI int -elm_win_rotation_get(const Evas_Object *obj) -{ - Efl_Ui_Win_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS); - if (!sd) return -1; - - return sd->rot; -} - EAPI int elm_win_wm_rotation_preferred_rotation_get(const Evas_Object *obj) { diff --git a/src/lib/elementary/efl_ui_win.eo b/src/lib/elementary/efl_ui_win.eo index c0d06576b1..6c43af09b2 100644 --- a/src/lib/elementary/efl_ui_win.eo +++ b/src/lib/elementary/efl_ui_win.eo @@ -1,3 +1,5 @@ +import efl_orientation; + enum Efl.Ui.Win_Type { [[Defines the types of window that can be created @@ -845,6 +847,21 @@ class @beta Efl.Ui.Win extends Efl.Ui.Widget implements Efl.Canvas.Scene, Efl.Ac } return: iterator; [[Iterator to pointer positions]] } + @property win_rotation @beta { + [[The rotation of this window + + The value will automatically change when the WM of this window changes its rotation. This rotation is automatically applied to all @Efl.Ui.Layout objects. + ]] + set { + legacy: null; + } + get { + legacy: null; + } + values { + rotation : Efl.Orient; [[The rotation of the window]] + } + } } implements { class.constructor; diff --git a/src/lib/elementary/elm_main.c b/src/lib/elementary/elm_main.c index 71e4325221..cc63a8e656 100644 --- a/src/lib/elementary/elm_main.c +++ b/src/lib/elementary/elm_main.c @@ -1912,16 +1912,31 @@ elm_object_name_find(const Evas_Object *obj, const char *name, int recurse) EAPI void elm_object_orientation_mode_disabled_set(Evas_Object *obj, Eina_Bool disabled) { - Efl_Ui_Widget_Orientation_Mode mode = - disabled ? EFL_UI_WIDGET_ORIENTATION_MODE_DISABLED - : EFL_UI_WIDGET_ORIENTATION_MODE_DEFAULT; - efl_ui_widget_orientation_mode_set(obj, mode); + if (efl_isa(obj, EFL_UI_LAYOUT_CLASS)) + { + efl_ui_layout_automatic_theme_rotation_set(obj, disabled); + } + else + { + //legacy behaviour + if (disabled) + efl_key_data_set(obj, "__orientation_mode_disabled", (void*) (intptr_t) EINA_TRUE); + } } EAPI Eina_Bool elm_object_orientation_mode_disabled_get(const Evas_Object *obj) { - return efl_ui_widget_orientation_mode_get(obj) == EFL_UI_WIDGET_ORIENTATION_MODE_DISABLED; + if (efl_isa(obj, EFL_UI_LAYOUT_CLASS)) + { + return efl_ui_layout_automatic_theme_rotation_get(obj); + } + else + { + if (efl_key_data_get(obj, "__orientation_mode_disabled")) + return EINA_TRUE; + } + return EINA_FALSE; } EAPI Elm_Object_Item * diff --git a/src/lib/elementary/elm_widget.h b/src/lib/elementary/elm_widget.h index cdc2653831..cc95ff75aa 100644 --- a/src/lib/elementary/elm_widget.h +++ b/src/lib/elementary/elm_widget.h @@ -364,7 +364,6 @@ typedef struct _Elm_Widget_Smart_Data Efl_Ui_Scrollable_On_Show_Region on_show_region; Eina_Free_Cb on_show_region_data_free; - int orient_mode; /* -1 is disabled */ Elm_Focus_Move_Policy focus_move_policy; Elm_Focus_Region_Show_Mode focus_region_show_mode; diff --git a/src/lib/elementary/elm_widget_layout.h b/src/lib/elementary/elm_widget_layout.h index 5628067691..827398fec6 100644 --- a/src/lib/elementary/elm_widget_layout.h +++ b/src/lib/elementary/elm_widget_layout.h @@ -71,6 +71,7 @@ typedef struct _Elm_Layout_Smart_Data Eina_Bool can_access : 1; /**< This is true when all text(including textblock) parts can be accessible by accessibility. */ Eina_Bool destructed_is : 1; /**< This flag indicates if Efl.Ui.Layout destructor was called. This is needed to avoid unnecessary calculation of subobject deletion during layout object's deletion. */ Eina_Bool file_set : 1; /**< This flag indicates if Efl.Ui.Layout source is set from a file*/ + Eina_Bool automatic_orientation_apply : 1; } Efl_Ui_Layout_Data; /**