aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSangHyeon Lee <sh10233.lee@samsung.com>2016-10-05 15:36:04 +0900
committerSangHyeon Lee <sh10233.lee@samsung.com>2016-10-19 15:48:51 +0900
commit73095ad7ad7cf67c2c9a66787da6395bfbdd3e4a (patch)
tree523b77f90e049d65a0da6bf79df7c965825e2122
parentevas: Last fix... now it builds (diff)
downloadefl-73095ad7ad7cf67c2c9a66787da6395bfbdd3e4a.tar.gz
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
-rw-r--r--src/bin/elementary/test.c2
-rw-r--r--src/bin/elementary/test_gengrid.c208
-rw-r--r--src/lib/elementary/elm_gengrid.c317
-rw-r--r--src/lib/elementary/elm_gengrid_item.eo27
-rw-r--r--src/lib/elementary/elm_widget_gengrid.h14
5 files changed, 531 insertions, 37 deletions
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 2c3d4762b8..a4ca08bee0 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -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);
diff --git a/src/bin/elementary/test_gengrid.c b/src/bin/elementary/test_gengrid.c
index 2c1ea559c1..da256806a5 100644
--- a/src/bin/elementary/test_gengrid.c
+++ b/src/bin/elementary/test_gengrid.c
@@ -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);
+}
+
diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c
index ed7ba997e3..717b3061be 100644
--- a/src/lib/elementary/elm_gengrid.c
+++ b/src/lib/elementary/elm_gengrid.c
@@ -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);
diff --git a/src/lib/elementary/elm_gengrid_item.eo b/src/lib/elementary/elm_gengrid_item.eo
index 70ff7cdba8..c740ccc820 100644
--- a/src/lib/elementary/elm_gengrid_item.eo
+++ b/src/lib/elementary/elm_gengrid_item.eo
@@ -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;
diff --git a/src/lib/elementary/elm_widget_gengrid.h b/src/lib/elementary/elm_widget_gengrid.h
index 20df266658..6f28c38dcc 100644
--- a/src/lib/elementary/elm_widget_gengrid.h
+++ b/src/lib/elementary/elm_widget_gengrid.h
@@ -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;