efl/hints: add restricted and combined max size hints

these function the same as the min size hint versions and enable
distinction between internally-set max size hints and user-set max size
hints

@feature

ref T8122

Reviewed-by: Cedric BAIL <cedric.bail@free.fr>
Reviewed-by: Xavi Artigas <xavierartigas@yahoo.es>
Differential Revision: https://phab.enlightenment.org/D9553
This commit is contained in:
Mike Blumenkrantz 2019-08-12 11:14:49 -04:00 committed by Cedric BAIL
parent c3f78d8b4f
commit e1fda2cbdb
16 changed files with 170 additions and 36 deletions

View File

@ -136,7 +136,7 @@ _ecore_evas_object_callback_changed_size_hints(void *data, Evas *e EINA_UNUSED,
evas_object_size_hint_combined_min_get(obj, &w, &h);
ecore_evas_size_min_set(ee, w, h);
evas_object_size_hint_max_get(obj, &w, &h);
evas_object_size_hint_combined_max_get(obj, &w, &h);
if (w < 1) w = -1;
if (h < 1) h = -1;
ecore_evas_size_max_set(ee, w, h);

View File

@ -6021,7 +6021,7 @@ _edje_real_part_swallow_hints_update(Edje_Real_Part *rp)
Evas_Aspect_Control am = EVAS_ASPECT_CONTROL_NONE;
evas_object_size_hint_combined_min_get(rp->typedata.swallow->swallowed_object, &w1, &h1);
evas_object_size_hint_max_get(rp->typedata.swallow->swallowed_object, &w2, &h2);
evas_object_size_hint_combined_max_get(rp->typedata.swallow->swallowed_object, &w2, &h2);
evas_object_size_hint_aspect_get(rp->typedata.swallow->swallowed_object, &am, &aw, &ah);
rp->typedata.swallow->swallow_params.min.w = w1;
rp->typedata.swallow->swallow_params.min.h = h1;

View File

@ -75,6 +75,51 @@ interface Efl.Gfx.Hint
default for canvas objects).]]
}
}
@property hint_size_restricted_max {
[[Internal hints for an object's maximum size.
This is not a size enforcement in any way, it's just a hint
that should be used whenever appropriate.
Values -1 will be treated as unset hint components, when
queried by managers.
Note: This property is internal and meant for widget developers to
define the absolute maximum size of the object. EFL itself sets
this size internally, so any change to it from an application
might be ignored. Applications should use @.hint_size_max instead.
Note: It is an error for the @.hint_size_restricted_max to be smaller in either axis
than @.hint_size_restricted_min. In this scenario, the max size hint will be
prioritized over the user min size hint.
]]
set @protected {
[[This function is protected as it is meant for widgets to indicate
their "intrinsic" maximum size.
]]
}
get {
[[Get the "intrinsic" maximum size of this object.]]
}
values {
sz: Eina.Size2D; [[Maximum size (hint) in pixels.]]
}
}
@property hint_size_combined_max {
[[Read-only maximum size combining both @.hint_size_restricted_max and
@.hint_size_max hints.
@.hint_size_restricted_max is intended for mostly internal usage
and widget developers, and @.hint_size_max is intended to be
set from application side. @.hint_size_combined_max combines both values
by taking their repective maximum (in both width and height), and
is used internally to get an object's maximum size.
]]
get {}
values {
sz: Eina.Size2D; [[Maximum size (hint) in pixels.]]
}
}
@property hint_size_min {
[[Hints on the object's minimum size.
@ -111,6 +156,10 @@ interface Efl.Gfx.Hint
define the absolute minimum size of the object. EFL itself sets
this size internally, so any change to it from an application
might be ignored. Use @.hint_size_min instead.
Note: It is an error for the @.hint_size_restricted_max to be smaller in either axis
than @.hint_size_restricted_min. In this scenario, the max size hint will be
prioritized over the user min size hint.
]]
set @protected {
[[This function is protected as it is meant for widgets to indicate

View File

@ -53,7 +53,7 @@ _efl_ui_container_layout_item_init(Eo* o, Efl_Ui_Container_Item_Hints *item)
efl_gfx_hint_margin_get(o, &item[0].margin[0], &item[0].margin[1],
&item[1].margin[0], &item[1].margin[1]);
efl_gfx_hint_fill_get(o, &item[0].fill, &item[1].fill);
max = efl_gfx_hint_size_max_get(o);
max = efl_gfx_hint_size_combined_max_get(o);
min = efl_gfx_hint_size_combined_min_get(o);
efl_gfx_hint_aspect_get(o, &aspect_type, &aspect);
item[0].aspect = aspect.w;

View File

@ -67,8 +67,8 @@ static void
_sizing_eval(Evas_Object *obj)
{
Evas_Coord minw = -1, minh = -1, minw2 = -1, minh2 = -1;
Evas_Coord maxw = -1, maxh = -1, maxw2 = -1, maxh2 = -1;
int fingx = 0, fingy = 0;
Eina_Size2D max = EINA_SIZE2D(-1, -1), max2 = EINA_SIZE2D(-1, -1);
EFL_UI_FLIP_DATA_GET(obj, sd);
@ -77,14 +77,14 @@ _sizing_eval(Evas_Object *obj)
if (sd->back.content)
evas_object_size_hint_combined_min_get(sd->back.content, &minw2, &minh2);
if (sd->front.content)
evas_object_size_hint_max_get(sd->front.content, &maxw, &maxh);
max = efl_gfx_hint_size_combined_max_get(sd->front.content);
if (sd->back.content)
evas_object_size_hint_max_get(sd->back.content, &maxw2, &maxh2);
max2 = efl_gfx_hint_size_combined_max_get(sd->back.content);
if (minw2 > minw) minw = minw2;
if (minh2 > minh) minh = minh2;
if ((maxw2 >= 0) && (maxw2 < maxw)) maxw = maxw2;
if ((maxh2 >= 0) && (maxh2 < maxh)) maxh = maxh2;
if ((max2.w >= 0) && (max2.w < max.w)) max.w = max2.w;
if ((max2.h >= 0) && (max2.h < max.h)) max.h = max2.h;
if (sd->dir_enabled[ELM_FLIP_DIRECTION_UP]) fingy++;
if (sd->dir_enabled[ELM_FLIP_DIRECTION_DOWN]) fingy++;
@ -94,7 +94,7 @@ _sizing_eval(Evas_Object *obj)
elm_coords_finger_size_adjust(fingx, &minw, fingy, &minh);
efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
evas_object_size_hint_max_set(obj, maxw, maxh);
efl_gfx_hint_size_restricted_max_set(obj, max);
}
EOLIAN static Eina_Error

View File

@ -39,7 +39,10 @@ _sizing_eval(Evas_Object *obj,
if ((minw == cminw) && (minh == cminh)) return;
efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
evas_object_size_hint_max_set(obj, -1, -1);
if (elm_widget_is_legacy(obj))
evas_object_size_hint_max_set(obj, -1, -1);
else
efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
}
static void

View File

@ -803,7 +803,7 @@ _efl_ui_image_sizing_eval(Evas_Object *obj)
}
efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
evas_object_size_hint_max_set(obj, maxw, maxh);
efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(maxw, maxh));
if (sd->img)
{

View File

@ -111,13 +111,12 @@ _photocam_image_file_set(Evas_Object *obj, Efl_Ui_Image_Zoomable_Data *sd)
static void
_sizing_eval(Evas_Object *obj)
{
Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1;
Evas_Coord minw = 0, minh = 0;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
Eina_Size2D max = efl_gfx_hint_size_combined_max_get(wd->resize_obj);
evas_object_size_hint_max_get
(wd->resize_obj, &maxw, &maxh);
efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
evas_object_size_hint_max_set(obj, maxw, maxh);
efl_gfx_hint_size_restricted_max_set(obj, max);
}
static void

View File

@ -65,7 +65,7 @@ _item_size_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Lay
efl_gfx_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
efl_gfx_hint_align_get(item->layout, &align[0], &align[1]);
efl_gfx_hint_fill_get(item->layout, &fill[0], &fill[1]);
max = efl_gfx_hint_size_max_get(item->layout);
max = efl_gfx_hint_size_combined_max_get(item->layout);
// box outer margin
boxw -= boxl + boxr;

View File

@ -497,7 +497,7 @@ _hash_child_init_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key E
calc->aspect[1] = aspect.h;
efl_gfx_hint_margin_get(child->obj, &calc->margin[LEFT], &calc->margin[RIGHT],
&calc->margin[TOP], &calc->margin[BOTTOM]);
max = efl_gfx_hint_size_max_get(child->obj);
max = efl_gfx_hint_size_combined_max_get(child->obj);
min = efl_gfx_hint_size_combined_min_get(child->obj);
calc->max[0] = max.w;
calc->max[1] = max.h;

View File

@ -302,7 +302,7 @@ _efl_ui_scroller_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Scroller_Data
if (sd->content)
{
min = efl_gfx_hint_size_combined_min_get(sd->content);
max = efl_gfx_hint_size_max_get(sd->content);
max = efl_gfx_hint_size_combined_max_get(sd->content);
efl_gfx_hint_weight_get(sd->content, &xw, &yw);
}

View File

@ -963,7 +963,7 @@ _elm_win_size_hints_update(Efl_Ui_Win *win, Efl_Ui_Win_Data *sd)
Eina_Size2D min, max;
min = efl_gfx_hint_size_combined_min_get(win);
max = efl_gfx_hint_size_max_get(win);
max = efl_gfx_hint_size_combined_max_get(win);
if (max.w < 1) max.w = -1;
if (max.h < 1) max.h = -1;
@ -1637,7 +1637,7 @@ _win_rotate(Evas_Object *obj, Efl_Ui_Win_Data *sd, int rotation, Eina_Bool resiz
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));
efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(-1, -1));
_elm_win_resize_objects_eval(obj, EINA_FALSE);
#ifdef HAVE_ELEMENTARY_X
_elm_win_xwin_update(sd);
@ -3701,6 +3701,7 @@ _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize)
evas_object_size_hint_combined_min_get(sd->legacy.edje, &minw, &minh);
if ((!minw) && (!minh) && (!sd->deferred_resize_job)) return;
efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(-1, -1));
// If content has a weight, make resizable
efl_gfx_hint_weight_get(sd->legacy.edje, &wx, &wy);
@ -3722,6 +3723,7 @@ _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize)
if (maxh > 32767) maxh = 32767;
unresizable = ((minw == maxw) && (minh == maxh));
if (sd->csd.need_unresizable != unresizable)
{
sd->csd.need_unresizable = unresizable;
@ -3741,7 +3743,7 @@ _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize)
sd->tmp_updating_hints = 1;
efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
efl_gfx_hint_size_max_set(obj, EINA_SIZE2D(maxw, maxh));
efl_gfx_hint_size_restricted_max_set(obj, EINA_SIZE2D(maxw, maxh));
sd->tmp_updating_hints = 0;
_elm_win_size_hints_update(obj, sd);

View File

@ -61,6 +61,15 @@ evas_object_size_hint_combined_min_get(const Eo *obj, int *w, int *h)
if (h) *h = sz.h;
}
static inline void
evas_object_size_hint_combined_max_get(const Eo *obj, int *w, int *h)
{
Eina_Size2D sz;
sz = efl_gfx_hint_size_combined_max_get(obj);
if (w) *w = sz.w;
if (h) *h = sz.h;
}
/* Internal EO APIs */
EAPI Eo *evas_find(const Eo *obj);
EOAPI void efl_canvas_object_legacy_ctor(Eo *obj);

View File

@ -540,7 +540,9 @@ abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity,
Efl.Gfx.Hint.hint_aspect { get; set; }
Efl.Gfx.Hint.hint_align { get; set; }
Efl.Gfx.Hint.hint_size_combined_min { get; }
Efl.Gfx.Hint.hint_size_combined_max { get; }
Efl.Gfx.Hint.hint_size_restricted_min { get; set; }
Efl.Gfx.Hint.hint_size_restricted_max { get; set; }
Efl.Gfx.Hint.hint_size_min { get; set; }
Efl.Gfx.Hint.hint_size_max { get; set; }
Efl.Gfx.Hint.hint_margin { get; set; }

View File

@ -1405,6 +1405,8 @@ _evas_object_size_hint_alloc(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protec
obj->size_hints = EVAS_MEMPOOL_ALLOC(_mp_sh, Evas_Size_Hints);
if (!obj->size_hints) return;
EVAS_MEMPOOL_PREP(_mp_sh, obj->size_hints, Evas_Size_Hints);
obj->size_hints->user_max.w = -1;
obj->size_hints->user_max.h = -1;
obj->size_hints->max.w = -1;
obj->size_hints->max.h = -1;
obj->size_hints->align.x = 0.5;
@ -1443,6 +1445,37 @@ evas_object_size_hint_display_mode_set(Eo *eo_obj, Evas_Display_Mode dispmode)
evas_object_inform_call_changed_size_hints(eo_obj, obj);
}
EOLIAN static Eina_Size2D
_efl_canvas_object_efl_gfx_hint_hint_size_restricted_max_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
{
if ((!obj->size_hints) || obj->delete_me)
return EINA_SIZE2D(0, 0);
return obj->size_hints->max;
}
EOLIAN static void
_efl_canvas_object_efl_gfx_hint_hint_size_restricted_max_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Eina_Size2D sz)
{
if (obj->delete_me)
return;
EVAS_OBJECT_DATA_VALID_CHECK(obj);
evas_object_async_block(obj);
if (EINA_UNLIKELY(!obj->size_hints))
{
if (!sz.w && !sz.h) return;
_evas_object_size_hint_alloc(eo_obj, obj);
}
if ((obj->size_hints->max.w == sz.w) && (obj->size_hints->max.h == sz.h)) return;
obj->size_hints->max = sz;
if ((obj->size_hints->max.w != -1) && (obj->size_hints->max.w < obj->size_hints->min.w))
ERR("restricted max width hint is now smaller than restricted min width hint! (%d < %d)", obj->size_hints->max.w, obj->size_hints->min.w);
if ((obj->size_hints->max.h != -1) && (obj->size_hints->max.h < obj->size_hints->min.h))
ERR("restricted max height hint is now smaller than restricted min height hint! (%d < %d)", obj->size_hints->max.h, obj->size_hints->min.h);
evas_object_inform_call_changed_size_hints(eo_obj, obj);
}
EOLIAN static Eina_Size2D
_efl_canvas_object_efl_gfx_hint_hint_size_restricted_min_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
{
@ -1467,7 +1500,10 @@ _efl_canvas_object_efl_gfx_hint_hint_size_restricted_min_set(Eo *eo_obj, Evas_Ob
}
if ((obj->size_hints->min.w == sz.w) && (obj->size_hints->min.h == sz.h)) return;
obj->size_hints->min = sz;
if ((obj->size_hints->max.w != -1) && (obj->size_hints->max.w < obj->size_hints->min.w))
ERR("restricted max width hint is now smaller than restricted min width hint! (%d < %d)", obj->size_hints->max.w, obj->size_hints->min.w);
if ((obj->size_hints->max.h != -1) && (obj->size_hints->max.h < obj->size_hints->min.h))
ERR("restricted max height hint is now smaller than restricted min height hint! (%d < %d)", obj->size_hints->max.h, obj->size_hints->min.h);
evas_object_inform_call_changed_size_hints(eo_obj, obj);
}
@ -1486,19 +1522,53 @@ _efl_canvas_object_efl_gfx_hint_hint_size_combined_min_get(const Eo *eo_obj EINA
if (obj->size_hints->max.h != -1)
sz.h = obj->size_hints->max.h;
/* clamp user min to user max here */
/* clamp user min to restricted max here */
sz.w = MAX(obj->size_hints->min.w, MIN(sz.w, obj->size_hints->user_min.w));
sz.h = MAX(obj->size_hints->min.h, MIN(sz.h, obj->size_hints->user_min.h));
return sz;
}
EOLIAN static Eina_Size2D
_efl_canvas_object_efl_gfx_hint_hint_size_combined_max_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
{
Eina_Size2D sz = { -1, -1 };
if ((!obj->size_hints) || obj->delete_me)
return sz;
sz.w = obj->size_hints->user_max.w;
sz.h = obj->size_hints->user_max.h;
/* clamp user max to restricted max here */
if (obj->size_hints->max.w != -1)
{
if (sz.w == -1)
sz.w = obj->size_hints->max.w;
else
sz.w = MIN(obj->size_hints->max.w, sz.w);
}
if (obj->size_hints->max.h != -1)
{
if (sz.h == -1)
sz.h = obj->size_hints->max.h;
else
sz.h = MIN(obj->size_hints->max.h, sz.h);
}
/* then clamp to restricted min */
if ((sz.w != -1) && obj->size_hints->min.w > 0)
sz.w = MAX(sz.w, obj->size_hints->min.w);
if ((sz.h != -1) && obj->size_hints->min.h > 0)
sz.h = MAX(sz.h, obj->size_hints->min.h);
return sz;
}
EOLIAN static Eina_Size2D
_efl_canvas_object_efl_gfx_hint_hint_size_max_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
{
if ((!obj->size_hints) || obj->delete_me)
return EINA_SIZE2D(-1, -1);
return obj->size_hints->max;
return obj->size_hints->user_max;
}
EOLIAN static void
@ -1514,13 +1584,13 @@ _efl_canvas_object_efl_gfx_hint_hint_size_max_set(Eo *eo_obj, Evas_Object_Protec
if ((sz.w == -1) && (sz.h == -1)) return;
_evas_object_size_hint_alloc(eo_obj, obj);
}
if ((obj->size_hints->max.w == sz.w) && (obj->size_hints->max.h == sz.h)) return;
obj->size_hints->max.w = sz.w;
obj->size_hints->max.h = sz.h;
if ((obj->size_hints->max.w != -1) && (obj->size_hints->max.w < obj->size_hints->user_min.w))
ERR("max width hint is now smaller than user_min width hint! (%d < %d)", obj->size_hints->max.w, obj->size_hints->user_min.w);
if ((obj->size_hints->max.h != -1) && (obj->size_hints->max.h < obj->size_hints->user_min.h))
ERR("max height hint is now smaller than user_min height hint! (%d < %d)", obj->size_hints->max.h, obj->size_hints->user_min.h);
if ((obj->size_hints->user_max.w == sz.w) && (obj->size_hints->user_max.h == sz.h)) return;
obj->size_hints->user_max.w = sz.w;
obj->size_hints->user_max.h = sz.h;
if ((obj->size_hints->user_max.w != -1) && (obj->size_hints->user_max.w < obj->size_hints->user_min.w))
ERR("user_max width hint is now smaller than user_min width hint! (%d < %d)", obj->size_hints->user_max.w, obj->size_hints->user_min.w);
if ((obj->size_hints->user_max.h != -1) && (obj->size_hints->user_max.h < obj->size_hints->user_min.h))
ERR("user_max height hint is now smaller than user_min height hint! (%d < %d)", obj->size_hints->user_max.h, obj->size_hints->user_min.h);
evas_object_inform_call_changed_size_hints(eo_obj, obj);
}
@ -1584,10 +1654,10 @@ _efl_canvas_object_efl_gfx_hint_hint_size_min_set(Eo *eo_obj, Evas_Object_Protec
}
if ((obj->size_hints->user_min.w == sz.w) && (obj->size_hints->user_min.h == sz.h)) return;
obj->size_hints->user_min = sz;
if ((obj->size_hints->max.w != -1) && (obj->size_hints->max.w < obj->size_hints->user_min.w))
ERR("max width hint is now smaller than user_min width hint! (%d < %d)", obj->size_hints->max.w, obj->size_hints->user_min.w);
if ((obj->size_hints->max.h != -1) && (obj->size_hints->max.h < obj->size_hints->user_min.h))
ERR("max height hint is now smaller than user_min height hint! (%d < %d)", obj->size_hints->max.h, obj->size_hints->user_min.h);
if ((obj->size_hints->user_max.w != -1) && (obj->size_hints->max.w < obj->size_hints->user_min.w))
ERR("max width hint is now smaller than min width hint! (%d < %d)", obj->size_hints->user_max.w, obj->size_hints->user_min.w);
if ((obj->size_hints->user_max.h != -1) && (obj->size_hints->max.h < obj->size_hints->user_min.h))
ERR("max height hint is now smaller than min height hint! (%d < %d)", obj->size_hints->user_max.h, obj->size_hints->user_min.h);
evas_object_inform_call_changed_size_hints(eo_obj, obj);
}

View File

@ -959,7 +959,7 @@ struct _Evas_Double_Pair
struct _Evas_Size_Hints
{
Evas_Size request;
Eina_Size2D min, user_min, max;
Eina_Size2D min, user_min, max, user_max;
Evas_Aspect aspect;
Evas_Double_Pair align, weight;
Evas_Border padding;