Elm.Win: Implement container & pack APIs

This replaces resize_object APIs.
This commit is contained in:
Jean-Philippe Andre 2016-04-25 18:15:19 +09:00
parent f19da66843
commit f7f1862489
4 changed files with 162 additions and 53 deletions

View File

@ -15,6 +15,8 @@
# include "ecore_evas_wayland_private.h"
#endif
#include "../evas/canvas/evas_box.eo.h"
#define MY_CLASS ELM_WIN_CLASS
#define MY_CLASS_NAME "Elm_Win"
@ -93,6 +95,7 @@ static const Elm_Win_Trap *trap = NULL;
#define ENGINE_GET() (_elm_preferred_engine ? _elm_preferred_engine : _elm_config->engine)
typedef struct _Elm_Win_Data Elm_Win_Data;
typedef struct _Box_Item_Iterator Box_Item_Iterator;
struct _Elm_Win_Data
{
@ -235,6 +238,14 @@ struct _Elm_Win_Data
Eina_Bool application_alpha : 1; /**< alpha value set by an elm_win_alpha_set() api. this has lower priority than theme_alpha */
};
struct _Box_Item_Iterator
{
Eina_Iterator iterator;
Eina_List *list;
Eina_Iterator *real_iterator;
Eo *object;
};
static const char SIG_DELETE_REQUEST[] = "delete,request";
static const char SIG_FOCUS_OUT[] = "focus,out"; // deprecated. use "unfocused" instead.
static const char SIG_FOCUS_IN[] = "focus,in"; // deprecated. use "focused" instead.
@ -4154,21 +4165,99 @@ elm_win_util_dialog_add(Evas_Object *parent, const char *name, const char *title
}
EOLIAN static void
_elm_win_resize_object_add(Eo *obj, Elm_Win_Data *sd, Evas_Object *subobj)
_elm_win_efl_pack_pack(Eo *obj, Elm_Win_Data *sd, Efl_Gfx_Base *subobj)
{
elm_widget_sub_object_add(obj, subobj);
Eina_Bool ret;
if (!evas_object_box_append(sd->box, subobj))
ERR("could not append %p to box", subobj);
ret = elm_widget_sub_object_add(obj, subobj);
ret &= (evas_object_box_append(sd->box, subobj) != NULL);
if (!ret)
ERR("could not add sub object %p to window %p", subobj, obj);
//return ret;
}
EOLIAN static void
_elm_win_resize_object_del(Eo *obj, Elm_Win_Data *sd, Evas_Object *subobj)
EOLIAN static Eina_Bool
_elm_win_efl_pack_unpack(Eo *obj, Elm_Win_Data *sd, Efl_Gfx_Base *subobj)
{
if (!elm_widget_sub_object_del(obj, subobj))
ERR("could not remove sub object %p from %p", subobj, obj);
Eina_Bool ret;
evas_object_box_remove(sd->box, subobj);
ret = elm_widget_sub_object_del(obj, subobj);
ret &= evas_object_box_remove(sd->box, subobj);
if (!ret)
ERR("could not remove sub object %p from window %p", subobj, obj);
return ret;
}
EOLIAN static Eina_Bool
_elm_win_efl_container_content_remove(Eo *obj, Elm_Win_Data *sd EINA_UNUSED,
Efl_Gfx_Base *subobj)
{
return efl_pack_unpack(obj, subobj);
}
EOLIAN static int
_elm_win_efl_container_content_count(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
{
Evas_Object_Box_Data *bd;
bd = eo_data_scope_get(sd->box, EVAS_BOX_CLASS);
if (!bd) return 0;
return eina_list_count(bd->children);
}
/* same as efl.ui.box but container is an elm win */
static Eina_Bool
_box_item_iterator_next(Box_Item_Iterator *it, void **data)
{
Efl_Gfx_Base *sub;
if (!eina_iterator_next(it->real_iterator, (void **) &sub))
return EINA_FALSE;
if (data) *data = sub;
return EINA_TRUE;
}
static Elm_Layout *
_box_item_iterator_get_container(Box_Item_Iterator *it)
{
return it->object;
}
static void
_box_item_iterator_free(Box_Item_Iterator *it)
{
eina_iterator_free(it->real_iterator);
eina_list_free(it->list);
free(it);
}
EOLIAN static Eina_Iterator *
_elm_win_efl_container_content_iterate(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
{
Box_Item_Iterator *it;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
it = calloc(1, sizeof(*it));
if (!it) return NULL;
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->list = evas_object_box_children_get(sd->box);
it->real_iterator = eina_list_iterator_new(it->list);
it->iterator.version = EINA_ITERATOR_VERSION;
it->iterator.next = FUNC_ITERATOR_NEXT(_box_item_iterator_next);
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_box_item_iterator_get_container);
it->iterator.free = FUNC_ITERATOR_FREE(_box_item_iterator_free);
it->object = obj;
return &it->iterator;
}
EOLIAN static void
@ -5837,4 +5926,19 @@ _elm_win_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Win_Data *sd EINA_
return name ? strdup(name) : NULL;
}
/* legacy APIs */
EAPI void
elm_win_resize_object_add(Eo *obj, Evas_Object *subobj)
{
efl_pack(obj, subobj);
}
EAPI void
elm_win_resize_object_del(Eo *obj, Evas_Object *subobj)
{
efl_pack_unpack(obj, subobj);
}
#include "elm_win.eo.c"

View File

@ -163,7 +163,7 @@ enum Elm.Illume_Command
}
class Elm.Win (Elm.Widget, Elm.Interface_Atspi_Window,
Elm.Interface_Atspi_Widget_Action)
Elm.Interface_Atspi_Widget_Action, Efl.Pack)
{
eo_prefix: elm_obj_win;
methods {
@ -1172,36 +1172,6 @@ class Elm.Win (Elm.Widget, Elm.Interface_Atspi_Window,
window will be the active one after it.
]]
}
resize_object_add {
[[Add $subobj as a resize object of window $obj.
Setting an object as a resize object of the window means that
the $subobj child's size and position will be controlled by the
window directly. That is, the object will be resized to match
the window size and should never be moved or resized manually
by the developer.
In addition, resize objects of the window control what the
minimum size of it will be, as well as whether it can or not
be resized by the user.
For the end user to be able to resize a window by dragging the
handles or borders provided by the Window Manager, or using any
other similar mechanism, all of the resize objects in the window
should have their \@ref evas_object_size_hint_weight_set set to
EVAS_HINT_EXPAND.
Also notice that the window can get resized to the current size
of the object if the EVAS_HINT_EXPAND is set after the call to
this. So if the object should get resized to the size of the
window, set this hint before adding it as a resize object (this
happens because the size of the window and the object are
evaluated as soon as the object is added to the window).
]]
params {
@in subobj: Evas.Object *; [[The resize object to add.]]
}
}
raise {
[[Raise a window object.
@ -1222,18 +1192,6 @@ class Elm.Win (Elm.Widget, Elm.Interface_Atspi_Window,
request.
]]
}
resize_object_del {
[[Delete $subobj as a resize object of window $obj.
This function removes the object $subobj from the resize objects
of the window $obj. It will not delete the object itself, which
will be left unmanaged and should be deleted by the developer,
manually handled or set as child of some other container.
]]
params {
@in subobj: Evas.Object *; [[The resize object to add.]]
}
}
center {
[[Center a window on its screen
@ -1295,6 +1253,11 @@ class Elm.Win (Elm.Widget, Elm.Interface_Atspi_Window,
Elm.Interface_Atspi_Accessible.state_set.get;
Elm.Interface_Atspi_Accessible.name.get;
Elm.Interface_Atspi_Widget_Action.elm_actions.get;
Efl.Container.content_remove;
Efl.Container.content_iterate;
Efl.Container.content_count;
Efl.Pack.unpack;
Efl.Pack.pack;
}
constructors {
.name;

View File

@ -244,3 +244,45 @@ EAPI void elm_win_wm_rotation_preferred_rotation_set(const Evas
* this is definitely not the function you are looking for.
*/
EAPI Ecore_Window elm_win_window_id_get(const Evas_Object *obj);
/**
* @brief Add @c subobj as a resize object of window @c obj.
*
* Setting an object as a resize object of the window means that the @c subobj
* child's size and position will be controlled by the window directly. That
* is, the object will be resized to match the window size and should never be
* moved or resized manually by the developer.
*
* In addition, resize objects of the window control what the minimum size of
* it will be, as well as whether it can or not be resized by the user.
*
* For the end user to be able to resize a window by dragging the handles or
* borders provided by the Window Manager, or using any other similar
* mechanism, all of the resize objects in the window should have their @ref
* evas_object_size_hint_weight_set set to EVAS_HINT_EXPAND.
*
* Also notice that the window can get resized to the current size of the
* object if the EVAS_HINT_EXPAND is set after the call to this. So if the
* object should get resized to the size of the window, set this hint before
* adding it as a resize object (this happens because the size of the window
* and the object are evaluated as soon as the object is added to the window).
*
* @param[in] subobj The resize object to add.
*
* @ingroup Elm_Win
*/
EAPI void elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj);
/**
* @brief Delete @c subobj as a resize object of window @c obj.
*
* This function removes the object @c subobj from the resize objects of the
* window @c obj. It will not delete the object itself, which will be left
* unmanaged and should be deleted by the developer, manually handled or set as
* child of some other container.
*
* @param[in] subobj The resize object to add.
*
* @ingroup Elm_Win
*/
EAPI void elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj);

View File

@ -27,7 +27,7 @@ _elm_win_standard_eo_base_finalize(Eo *obj, void *pd EINA_UNUSED)
return NULL;
}
evas_obj_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_obj_win_resize_object_add(obj, bg);
efl_pack(obj, bg);
efl_gfx_visible_set(bg, EINA_TRUE);
return obj;