gengrid: support for non homogenous items

Summary:
Dimensions of gengrid items can be altered for
non homogenity.

Care must be taken however to set the homogenous
size for items using elm_gengrid_item_size_set().

In horizontal mode only the heights will change
and in vertical mode only the widths. Fixed dimension
will be as set with elm_gengrid_item_size_set().

This is forked by https://phab.enlightenment.org/D2422

Test Plan:
elementary_test -to "Gengrid Resized Items"
Current test program provides focus autoscroll
and item looping options.

Reviewers: raster

Subscribers: cedric, jpeg

Differential Revision: https://phab.enlightenment.org/D4330
This commit is contained in:
SangHyeon Lee 2016-10-05 15:36:04 +09:00
parent b88093c847
commit 73095ad7ad
5 changed files with 531 additions and 37 deletions

View File

@ -156,6 +156,7 @@ void test_gengrid_speed(void *data, Evas_Object *obj, void *event_info);
void test_gengrid_focus(void *data, Evas_Object *obj, void *event_info);
void test_gengrid_update(void *data, Evas_Object *obj, void *event_info);
void test_gengrid_disabled_item_focus(void *data, Evas_Object *obj, void *event_info);
void test_gengrid_item_custom_size(void *data, Evas_Object *obj, void *event_info);
void test_win_state(void *data, Evas_Object *obj, void *event_info);
void test_win_state2(void *data, Evas_Object *obj, void *event_info);
void test_progressbar(void *data, Evas_Object *obj, void *event_info);
@ -803,6 +804,7 @@ add_tests:
ADD_TEST(NULL, "Lists - Gengrid", "GenGrid Focus", test_gengrid_focus);
ADD_TEST(NULL, "Lists - Gengrid", "GenGrid Update", test_gengrid_update);
ADD_TEST(NULL, "Lists - Gengrid", "GenGrid Disabled Item Focus", test_gengrid_disabled_item_focus);
ADD_TEST(NULL, "Lists - Gengrid", "GenGrid Item Custom Size", test_gengrid_item_custom_size);
//------------------------------//
ADD_TEST(NULL, "General", "Scaling", test_scaling);

View File

@ -5,6 +5,8 @@
#endif
#include <Elementary.h>
#define ITEMS_MAX 50
Evas_Object * _focus_autoscroll_mode_frame_create(Evas_Object *parent);
static Elm_Gengrid_Item_Class *gic, *ggic;
@ -2336,3 +2338,209 @@ test_gengrid_disabled_item_focus(void *data EINA_UNUSED,
evas_object_resize(win, 600, 600);
evas_object_show(win);
}
static void
_enable_bringin(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
if (elm_check_state_get(obj))
elm_config_focus_autoscroll_mode_set(ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN);
else
elm_config_focus_autoscroll_mode_set(ELM_FOCUS_AUTOSCROLL_MODE_SHOW);
}
typedef struct _item_resize_data{
Evas_Object *wentry, *hentry, *grid;
}Item_Resize_Data;
static void
_custom_item_size(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Coord w = 0, h = 0;
Elm_Object_Item *it;
const char *pstr;
Item_Resize_Data *pdata;
if (!data) return;
pdata = data;
pstr = elm_object_text_get(pdata->wentry);
if (pstr) w = atoi(pstr);
pstr = elm_object_text_get(pdata->hentry);
if (pstr) h = atoi(pstr);
it = elm_gengrid_selected_item_get(pdata->grid);
if (it) elm_gengrid_item_custom_size_set(it, w, h);
}
static void
_item_selected(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Evas_Coord w, h;
Item_Resize_Data *pdata;
char buf[8];
if (!data) return;
pdata = data;
elm_gengrid_item_custom_size_get(event_info, &w, &h);
if (snprintf(buf, 8, "%d", (int)w) > 7) buf[7] = 0;
elm_object_part_text_set(pdata->wentry, NULL, buf);
if (snprintf(buf, 8, "%d", (int)h) > 7) buf[7] = 0;
elm_object_part_text_set(pdata->hentry, NULL, buf);
}
void
test_gengrid_item_custom_size(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Evas_Object *win, *hbox, *vbox, *ck, *grid, *en, *btn, *ebox, *lb;
Elm_Gengrid_Item_Class *ic;
Item_Data *id;
Item_Resize_Data *pdata;
char buf[PATH_MAX];
int i, n;
pdata = calloc(1, sizeof(Item_Resize_Data));
win = elm_win_util_standard_add("item custom size", "Item Custom Size");
elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _cleanup_cb, pdata);
elm_win_autodel_set(win, EINA_TRUE);
evas_object_show(win);
hbox = elm_box_add(win);
elm_box_horizontal_set(hbox, EINA_TRUE);
evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_win_resize_object_add(win, hbox);
evas_object_show(hbox);
/* box for gengrid */
vbox = elm_box_add(hbox);
evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(hbox, vbox);
evas_object_show(vbox);
grid = elm_gengrid_add(vbox);
/* Set default size of items even if elm_gengrid_item_custom_size_set()
* will be used to set custom size for individual item. */
elm_gengrid_item_size_set(grid, ELM_SCALE_SIZE(100), ELM_SCALE_SIZE(100));
elm_gengrid_horizontal_set(grid, EINA_TRUE);
evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(vbox, grid);
evas_object_show(grid);
pdata->grid = grid;
evas_object_smart_callback_add(grid, "item,focused", _gengrid_focus_item_cb, "item,focused");
evas_object_smart_callback_add(grid, "item,unfocused", _gengrid_focus_item_cb, "item,unfocused");
evas_object_smart_callback_add(grid, "selected", _gengrid_focus_item_cb, "selected");
evas_object_smart_callback_add(grid, "unselected", _gengrid_focus_item_cb, "unselected");
evas_object_smart_callback_add(grid, "activated", _gengrid_focus_item_cb, "activated");
evas_object_smart_callback_add(grid, "highlighted", _gengrid_focus_item_cb, "highlighted");
evas_object_smart_callback_add(grid, "unhighlighted", _gengrid_focus_item_cb, "unhighlighted");
/* box for options */
vbox = elm_box_add(hbox);
elm_box_padding_set(vbox, 0, 20);
evas_object_size_hint_weight_set(vbox, 0.0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(hbox, vbox);
evas_object_show(vbox);
ebox = elm_box_add(vbox);
elm_box_padding_set(ebox, 0, 5);
evas_object_size_hint_weight_set(ebox, 0.0, 0.0);
evas_object_size_hint_align_set(ebox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(vbox, ebox);
evas_object_show(ebox);
lb = elm_label_add(ebox);
elm_object_text_set(lb, "Select an item...");
evas_object_size_hint_weight_set(lb, 0.0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(ebox, lb);
evas_object_show(lb);
en = elm_entry_add(ebox);
elm_entry_single_line_set(en, EINA_TRUE);
elm_entry_scrollable_set(en, EINA_TRUE);
elm_object_part_text_set(en, "guide", "Width");
evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(ebox, en);
evas_object_show(en);
pdata->wentry = en;
en = elm_entry_add(ebox);
elm_entry_single_line_set(en, EINA_TRUE);
elm_entry_scrollable_set(en, EINA_TRUE);
elm_object_part_text_set(en, "guide", "Height");
evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(ebox, en);
evas_object_show(en);
pdata->hentry = en;
btn = elm_button_add(ebox);
elm_object_text_set(btn, "Resize Item");
evas_object_smart_callback_add(btn, "clicked", _custom_item_size, (void *)pdata);
elm_box_pack_end(ebox, btn);
evas_object_show(btn);
ebox = elm_box_add(vbox);
evas_object_size_hint_weight_set(ebox, 0.0, 0.0);
evas_object_size_hint_align_set(ebox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(vbox, ebox);
evas_object_show(ebox);
ck = elm_check_add(ebox);
elm_object_text_set(ck, "Horizontal Mode");
evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, 0.0);
evas_object_smart_callback_add(ck, "changed", _horizontal_grid, grid);
elm_check_state_set(ck, EINA_TRUE);
elm_box_pack_end(ebox, ck);
evas_object_show(ck);
ck = elm_check_add(ebox);
elm_object_text_set(ck, "Bring-in");
evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, 0.0);
evas_object_smart_callback_add(ck, "changed", _enable_bringin, grid);
elm_box_pack_end(ebox, ck);
evas_object_show(ck);
ck = elm_check_add(ebox);
elm_object_text_set(ck, "Item Loop");
evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, 0.0);
evas_object_smart_callback_add(ck, "changed",_item_loop_enable_changed_cb, grid);
elm_box_pack_end(ebox, ck);
evas_object_show(ck);
ic = elm_gengrid_item_class_new();
ic->item_style = "default";
ic->func.text_get = grid_text_get;
ic->func.content_get = grid_content_get;
ic->func.state_get = NULL;
ic->func.del = grid_del;
n = 0;
for (i = 0; i < ITEMS_MAX; i++)
{
id = calloc(1, sizeof(Item_Data));
snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(), img[n]);
n = (n + 1) % 9;
id->mode = i;
id->path = eina_stringshare_add(buf);
id->item = elm_gengrid_item_append(grid, ic, id, _item_selected, pdata);
if (!(i % 2))
elm_gengrid_item_custom_size_set(id->item, ELM_SCALE_SIZE(40 + (2 * i)),
ELM_SCALE_SIZE(40 + (2 * i)));
}
elm_gengrid_item_class_free(ic);
evas_object_resize(win, 800, 600);
}

View File

@ -94,7 +94,7 @@ static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
static void _item_position_update(Eina_Inlist *list, int idx);
static void _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view);
static void _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view);
static void _calc_job(void *data);
static const Elm_Action key_actions[] = {
{"move", _key_action_move},
@ -264,6 +264,66 @@ _item_cache_find(Elm_Gen_Item *it)
return EINA_FALSE;
}
//Calculate sum of widths or heights of all items in a row or column
static int
_get_item_span(Elm_Gengrid_Data *sd, int idx)
{
Elm_Gen_Item *it;
int sum = 0;
idx++;
EINA_INLIST_FOREACH(sd->items, it)
{
if (it->position == idx)
{
sum += ((sd->horizontal) ? it->item->w : it->item->h);
idx += sd->nmax;
}
}
return sum;
}
static Eina_Bool
_setup_custom_size_mode(Elm_Gengrid_Data *sd)
{
unsigned int *tmp;
int alloc_size = sd->nmax * sizeof(unsigned int);
if (sd->nmax <= sd->custom_alloc_size) return EINA_TRUE;
tmp = realloc(sd->custom_size_sum, alloc_size);
if (!tmp) return EINA_FALSE;
sd->custom_size_sum = tmp;
tmp = realloc(sd->custom_tot_sum, alloc_size);
if (!tmp) return EINA_FALSE;
sd->custom_tot_sum = tmp;
sd->custom_alloc_size = sd->nmax;
return EINA_TRUE;
}
static inline void
_cleanup_custom_size_mode(Elm_Gengrid_Data *sd)
{
ELM_SAFE_FREE(sd->custom_size_sum, free);
ELM_SAFE_FREE(sd->custom_tot_sum, free);
}
static void
_custom_size_mode_calc(Elm_Gengrid_Data *sd)
{
unsigned int i, max;
if (!sd->custom_tot_sum) return;
max = sd->custom_tot_sum[0] = _get_item_span(sd, 0);
for (i = 1; i < sd->custom_alloc_size; ++i)
{
sd->custom_tot_sum[i] = _get_item_span(sd, i);
max = (max < sd->custom_tot_sum[i]) ? sd->custom_tot_sum[i] : max;
}
sd->custom_tot_max = max;
}
static Eina_Bool
_is_no_select(Elm_Gen_Item *it)
{
@ -277,6 +337,36 @@ _is_no_select(Elm_Gen_Item *it)
return EINA_FALSE;
}
EOLIAN static void
_elm_gengrid_item_custom_size_get(Eo *eo_it EINA_UNUSED,
Elm_Gen_Item *it,
Evas_Coord *w,
Evas_Coord *h)
{
ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
if (w) *w = GG_IT(it)->w;
if (h) *h = GG_IT(it)->h;
}
EOLIAN static void
_elm_gengrid_item_custom_size_set(Eo *eo_it EINA_UNUSED,
Elm_Gen_Item *it,
Evas_Coord w,
Evas_Coord h)
{
ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
ELM_GENGRID_DATA_GET_FROM_ITEM(it, sd);
if (!sd->custom_size_mode) sd->custom_size_mode = !sd->custom_size_mode;
if ((GG_IT(it)->w == w) && (GG_IT(it)->h == h)) return;
GG_IT(it)->h = h;
GG_IT(it)->w = w;
ecore_job_del(sd->calc_job);
sd->calc_job = ecore_job_add(_calc_job, sd->obj);
}
EOLIAN static Elm_Object_Item *
_elm_gengrid_search_by_text_item_get(Eo *obj EINA_UNUSED,
Elm_Gengrid_Data *sd,
@ -324,13 +414,15 @@ static void
_item_show_region(void *data)
{
Elm_Gengrid_Data *sd = data;
Evas_Coord cvw, cvh, it_xpos = 0, it_ypos = 0, minx = 0, miny = 0;
Evas_Coord cvw, cvh, it_xpos = 0, it_ypos = 0, col = 0, row = 0, minx = 0, miny = 0;
Evas_Coord vw = 0, vh = 0;
Elm_Object_Item *eo_it = NULL;
Eina_Bool was_resized = EINA_FALSE;
evas_object_geometry_get(sd->pan_obj, NULL, NULL, &cvw, &cvh);
if ((cvw != 0) && (cvh != 0))
{
int x = 0;
if (sd->show_region)
eo_it = sd->show_it;
else if (sd->bring_in)
@ -342,21 +434,91 @@ _item_show_region(void *data)
elm_obj_pan_pos_min_get(sd->pan_obj, &minx, &miny);
if (sd->horizontal && (sd->item_height > 0))
{
if (it->x >= 1)
it_xpos = ((it->x - GG_IT(it)->prev_group) * sd->item_width)
+ (GG_IT(it)->prev_group * sd->group_item_width)
+ minx;
else it_xpos = minx;
row = cvh / sd->item_height;
if (row <= 0) row = 1;
was_resized = sd->custom_size_mode && (it->y < (Evas_Coord)sd->custom_alloc_size);
if (was_resized)
{
it_xpos = GG_IT(it)->sw
+ ((sd->custom_tot_max - sd->custom_tot_sum[it->y]) * sd->align_x)
+ (GG_IT(it)->prev_group * sd->group_item_width)
+ minx;
}
else
{
col = sd->item_count / row;
if (elm_widget_mirrored_get(sd->obj))
{
if (sd->item_count % row == 0)
x = col - 1 - it->x;
else
x = col - it->x;
}
else x = it->x;
if (x >= 1)
{
it_xpos = ((x - GG_IT(it)->prev_group) * sd->item_width)
+ (GG_IT(it)->prev_group * sd->group_item_width)
+ minx;
}
else it_xpos = minx;
/**
* If custom size cannot be used for a row
* account for offset due to rows which are
* using custom sizes already.
*/
if (sd->custom_alloc_size > 0)
{
if (sd->item_count % row)
col++;
it_xpos += (sd->custom_tot_max
- ((col - GG_IT(it)->prev_group) * sd->item_width)
+ (GG_IT(it)->prev_group * sd->group_item_width)) * sd->align_x;
}
}
miny = miny + ((cvh - (sd->item_height * row))
* sd->align_y);
it_ypos = it->y * sd->item_height + miny;
}
else if (sd->item_width > 0)
{
col = cvw / sd->item_width;
if (col <= 0) col = 1;
was_resized = it->x < (Evas_Coord)sd->custom_alloc_size;
if (was_resized)
{
it_ypos = GG_IT(it)->sh
+ ((sd->custom_tot_max - sd->custom_tot_sum[it->x]) * sd->align_y)
+ (GG_IT(it)->prev_group * sd->group_item_height)
+ miny;
}
else
{
if (it->y >= 1)
{
it_ypos = ((it->y - GG_IT(it)->prev_group) * sd->item_height)
+ (GG_IT(it)->prev_group * sd->group_item_height)
+ miny;
}
else it_ypos = miny;
/**
* If custom size cannot be used for a column
* account for offset due to columns which are
* using custom sizes already.
*/
if (sd->custom_alloc_size > 0)
{
row = sd->item_count / col;
if (sd->item_count % col)
row++;
it_ypos += (sd->custom_tot_max
- ((row - GG_IT(it)->prev_group) * sd->item_height)
+ (GG_IT(it)->prev_group * sd->group_item_height)) * sd->align_y;
}
}
minx = minx + ((cvw - (sd->item_width * col))
* sd->align_x);
it_xpos = it->x * sd->item_width + minx;
if (it->y >= 1)
it_ypos = ((it->y - GG_IT(it)->prev_group) * sd->item_height)
+ (GG_IT(it)->prev_group * sd->group_item_height)
+ miny;
else it_ypos = miny;
}
switch (sd->scroll_to_type)
@ -378,8 +540,8 @@ _item_show_region(void *data)
it_ypos = it_ypos - vh + sd->item_height;
break;
default:
vw = sd->item_width;
vh = sd->item_height;
vw = (sd->horizontal && was_resized) ? GG_IT(it)->w : sd->item_width;
vh = (!sd->horizontal && was_resized) ? GG_IT(it)->h : sd->item_height;
break;
}
@ -419,6 +581,15 @@ _calc_job(void *data)
if (nmax < 1)
nmax = 1;
sd->nmax = nmax;
if (sd->custom_size_mode)
{
if (!_setup_custom_size_mode(sd))
ERR("Failed to allocate memory for custom item size "
"calculations!: gengrid=%p", sd->obj);
_custom_size_mode_calc(sd);
}
EINA_INLIST_FOREACH(sd->items, it)
{
if (GG_IT(it)->prev_group != count_group)
@ -442,15 +613,23 @@ _calc_job(void *data)
count = sd->item_count + sd->items_lost - count_group;
if (sd->horizontal)
{
minw = (ceil(count / (float)nmax) * sd->item_width) +
(count_group * sd->group_item_width);
minh = nmax * sd->item_height;
if (sd->custom_size_mode && (sd->custom_alloc_size > 0))
minw = sd->custom_tot_max +
(count_group * sd->group_item_width);
else
minw = (ceil(count / (float)nmax) * sd->item_width) +
(count_group * sd->group_item_width);
}
else
{
minw = nmax * sd->item_width;
minh = (ceil(count / (float)nmax) * sd->item_height) +
(count_group * sd->group_item_height);
if (sd->custom_size_mode && (sd->custom_alloc_size > 0))
minh = sd->custom_tot_max +
(count_group * sd->group_item_height);
else
minh = (ceil(count / (float)nmax) * sd->item_height) +
(count_group * sd->group_item_height);
}
if ((minw != sd->minw) || (minh != sd->minh))
@ -1497,7 +1676,7 @@ _item_place(Elm_Gen_Item *it,
Evas_Coord x, y, ox, oy, cvx, cvy, cvw, cvh, iw, ih, ww;
Evas_Coord tch, tcw, alignw = 0, alignh = 0, vw, vh;
Eina_Bool reorder_item_move_forward = EINA_FALSE;
Eina_Bool was_realized;
Eina_Bool was_realized, can_resize;
Elm_Gen_Item_Type *item;
long items_count;
int item_pos;
@ -1530,8 +1709,14 @@ _item_place(Elm_Gen_Item *it,
if (items_count % items_visible)
columns++;
tcw = (wsd->item_width * columns) + (wsd->group_item_width *
eina_list_count(wsd->group_items));
/* If custom sizes cannot be applied to items
* of a row use default item size. */
can_resize = (wsd->custom_size_mode && (cy < (Evas_Coord)wsd->custom_alloc_size));
if (can_resize)
tcw = wsd->custom_tot_sum[cy];
else
tcw = (wsd->item_width * columns) + (wsd->group_item_width *
eina_list_count(wsd->group_items));
alignw = (vw - tcw) * wsd->align_x;
items_row = items_visible;
@ -1563,8 +1748,14 @@ _item_place(Elm_Gen_Item *it,
if (items_count % items_visible)
rows++;
tch = (wsd->item_height * rows) + (wsd->group_item_height *
eina_list_count(wsd->group_items));
/* If custom sizes cannot be applied to items
* of a column use to default item size. */
can_resize = (wsd->custom_size_mode && (cx < (Evas_Coord)wsd->custom_alloc_size));
if (can_resize)
tch = wsd->custom_tot_sum[cx];
else
tch = (wsd->item_height * rows) + (wsd->group_item_height *
eina_list_count(wsd->group_items));
alignh = (vh - tch) * wsd->align_y;
items_col = items_visible;
@ -1611,18 +1802,48 @@ _item_place(Elm_Gen_Item *it,
{
if (wsd->horizontal)
{
x = (((cx - item->prev_group) * wsd->item_width)
+ (item->prev_group * wsd->group_item_width)) -
wsd->pan_x + ox + alignw;
if (can_resize)
{
if (cx == 0) wsd->custom_size_sum[cy] = 0;
x = ((item->prev_group * wsd->item_width)
+ (item->prev_group * wsd->group_item_width)) -
wsd->pan_x + ox + alignw + wsd->custom_size_sum[cy];
if (elm_widget_mirrored_get(WIDGET(it)))
it->item->sw = wsd->custom_tot_sum[cy] - wsd->custom_size_sum[cy] - it->item->w;
else
it->item->sw = wsd->custom_size_sum[cy];
wsd->custom_size_sum[cy] += it->item->w;
}
else
{
x = (((cx - item->prev_group) * wsd->item_width)
+ (item->prev_group * wsd->group_item_width)) -
wsd->pan_x + ox + alignw;
}
y = (cy * wsd->item_height) - wsd->pan_y + oy + alignh;
}
else
{
if (can_resize)
{
if (cy == 0) wsd->custom_size_sum[cx] = 0;
y = ((item->prev_group * wsd->item_height)
+ (item->prev_group * wsd->group_item_height)) -
wsd->pan_y + oy + alignh + wsd->custom_size_sum[cx];
it->item->sh = wsd->custom_size_sum[cx];
wsd->custom_size_sum[cx] += it->item->h;
}
else
{
y = (((cy - item->prev_group)
* wsd->item_height) + (item->prev_group *
wsd->group_item_height)) -
wsd->pan_y + oy + alignh;
}
x = (cx * wsd->item_width) - wsd->pan_x + ox + alignw;
y = (((cy - item->prev_group)
* wsd->item_height) + (item->prev_group *
wsd->group_item_height)) -
wsd->pan_y + oy + alignh;
}
if (elm_widget_mirrored_get(WIDGET(it))) /* Switch items side
* and componsate for
@ -1630,10 +1851,13 @@ _item_place(Elm_Gen_Item *it,
* mode */
{
evas_object_geometry_get(WIDGET(it), NULL, NULL, &ww, NULL);
x = ww - x - wsd->item_width - wsd->pan_x - wsd->pan_x + ox + ox;
if (wsd->horizontal && can_resize)
x = ww - x - it->item->w - wsd->pan_x - wsd->pan_x + ox + ox;
else
x = ww - x - wsd->item_width - wsd->pan_x - wsd->pan_x + ox + ox;
}
iw = wsd->item_width;
ih = wsd->item_height;
iw = (wsd->horizontal && can_resize) ? it->item->w : wsd->item_width;
ih = (!wsd->horizontal && can_resize) ? it->item->h : wsd->item_height;
}
was_realized = it->realized;
@ -1652,8 +1876,12 @@ _item_place(Elm_Gen_Item *it,
{
if (it->parent->item->gx < ox)
{
it->parent->item->gx = x + wsd->item_width -
wsd->group_item_width;
if (wsd->custom_size_mode)
it->parent->item->gx = x + it->item->w -
wsd->group_item_width;
else
it->parent->item->gx = x + wsd->item_width -
wsd->group_item_width;
if (it->parent->item->gx > ox)
it->parent->item->gx = ox;
}
@ -1663,8 +1891,12 @@ _item_place(Elm_Gen_Item *it,
{
if (it->parent->item->gy < oy)
{
it->parent->item->gy = y + wsd->item_height -
wsd->group_item_height;
if (wsd->custom_size_mode)
it->parent->item->gy = y + it->item->h -
wsd->group_item_height;
else
it->parent->item->gy = y + wsd->item_height -
wsd->group_item_height;
if (it->parent->item->gy > oy)
it->parent->item->gy = oy;
}
@ -4243,6 +4475,10 @@ _elm_gengrid_item_new(Elm_Gengrid_Data *sd,
GG_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
GG_IT(it)->wsd = sd;
/* for non homogenous items */
it->item->w = sd->item_width;
it->item->h = sd->item_height;
it->group = it->itc->item_style &&
(!strcmp(it->itc->item_style, "group_index"));
sd->item_count++;
@ -4321,6 +4557,12 @@ _elm_gengrid_efl_canvas_group_group_add(Eo *obj, Elm_Gengrid_Data *priv)
evas_object_raise(priv->stack);
elm_interface_scrollable_extern_pan_set(obj, priv->pan_obj);
/* for non homogenous mode */
priv->custom_size_mode = EINA_FALSE;
priv->custom_size_sum = NULL;
priv->custom_tot_sum = NULL;
priv->custom_alloc_size = 0;
}
EOLIAN static void
@ -4329,6 +4571,7 @@ _elm_gengrid_efl_canvas_group_group_del(Eo *obj, Elm_Gengrid_Data *sd)
elm_gengrid_clear(obj);
ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
ELM_SAFE_FREE(sd->stack, evas_object_del);
_cleanup_custom_size_mode(sd);
_item_cache_zero(sd);
ecore_job_del(sd->calc_job);

View File

@ -129,6 +129,33 @@ class Elm.Gengrid.Item(Elm.Widget.Item)
mode: Elm.Object.Select_Mode(Elm.Object.Select_Mode.max); [[The selected mode]]
}
}
@property custom_size {
[[Custom size mode for non-homogeneous gengrid. ]]
get {
[[Get the dimensions of a gengrid item.
Gives the dimensions set with elm_gengrid_item_custom_size_set(). If the item
has not been modified values set with elm_gengrid_item_size_set() are obtained.
@since 1.19]]
}
set {
[[Resize dimensions of a gengrid item.
In case of a horizontal grid, only the widths only be resized and
in case of vertical only the heights can be resized. Item size
should be set by elm_gengrid_item_size_set() beforehand.
The values set by elm_gengrid_item_size_set() will be used for the
dimension that remains fixed.
@since 1.19]]
}
values {
w : Evas.Coord; [[The item's width.]]
h : Evas.Coord; [[The item's height.]]
}
}
/* init { FIXME
params {
Evas_Smart_Cb func;

View File

@ -135,6 +135,17 @@ struct _Elm_Gengrid_Data
* cache. */
int item_cache_count;
int item_cache_max;
/* custom dimensions may be set for any item.
* the logic for placing items requires that either item widths
* for horizontal gengrid or item height for vertical gengrid
* may be varied at once. */
Eina_Bool custom_size_mode : 1; /* a flag that items have custom sizes */
unsigned int *custom_size_sum; /* array to store sum of the widths for items placed already for each row or sum of heights for each column. this is to find location of next item. */
unsigned int *custom_tot_sum; /* array to store total sum of all widths or heights. this is used for item alignment calculations. */
unsigned int custom_tot_max; /* maximum of the total sums over all rows or columns. this is also used for item alignment calculations. */
unsigned int custom_alloc_size; /* amount of memory allocated to above dynamic arrays in terms of number of rows or columns. */
};
struct Elm_Gen_Item_Type
@ -153,6 +164,9 @@ struct Elm_Gen_Item_Type
Eina_Bool nocache_once : 1; /* do not use cache for
* this item only once */
Eina_Bool nocache : 1; /* do not use cache for this item */
/* for non homogenous items */
Evas_Coord w, h, sw, sh;
};
typedef struct _Item_Cache Item_Cache;