From: Ning Tang <tecto...@gmail.com> Layout add redraw function to set allocation for launchers.
Signed-off-by: Li Chen <cl.zhejiang.ch...@gmail.com> Signed-off-by: Yi Yuan <harryyuan910...@gmail.com> Signed-off-by: Ning Tang <tecto...@gmail.com> --- clients/tablet-shell.c | 177 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 141 insertions(+), 36 deletions(-) diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c index f6e3bd2..54fb5b0 100644 --- a/clients/tablet-shell.c +++ b/clients/tablet-shell.c @@ -46,7 +46,6 @@ struct tablet { struct homescreen { struct window *window; struct widget *widget; - struct wl_list launcher_list; struct wl_list layout_list; }; @@ -76,7 +75,6 @@ struct layout { struct launcher { struct widget *widget; struct layout *layout; - struct homescreen *homescreen; cairo_surface_t *icon; int focused, pressed; char *path; @@ -90,6 +88,8 @@ static char *key_launcher_icon; static char *key_launcher_path; static void launcher_section_done(void *data); static void layout_section_done(void *data); +/* launcher size */ +static int launcher_size = 146; static const struct config_key shell_config_keys[] = { { "lockscreen-icon", CONFIG_KEY_STRING, &key_lockscreen_icon }, @@ -160,9 +160,7 @@ homescreen_draw(struct widget *widget, void *data) cairo_surface_t *surface; struct rectangle allocation; cairo_t *cr; - struct launcher *launcher; - const int rows = 4, columns = 5, icon_width = 128, icon_height = 128; - int x, y, i, width, height, vmargin, hmargin, vpadding, hpadding; + struct layout *layout; surface = window_get_surface(homescreen->window); cr = cairo_create(surface); @@ -170,32 +168,21 @@ homescreen_draw(struct widget *widget, void *data) widget_get_allocation(widget, &allocation); paint_background(cr, key_homescreen_background, &allocation); - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - - width = allocation.width - columns * icon_width; - hpadding = width / (columns + 1); - hmargin = (width - hpadding * (columns - 1)) / 2; - - height = allocation.height - rows * icon_height; - vpadding = height / (rows + 1); - vmargin = (height - vpadding * (rows - 1)) / 2; - - x = hmargin; - y = vmargin; - i = 0; - - wl_list_for_each(launcher, &homescreen->launcher_list, link) { - widget_set_allocation(launcher->widget, - x, y, icon_width, icon_height); - x += icon_width + hpadding; - i++; - if (i == columns) { - x = hmargin; - y += icon_height + vpadding; - i = 0; + /* draw current layout */ + wl_list_for_each(layout, &homescreen->layout_list, link) { + if (layout->showing) { + widget_set_allocation(layout->widget, + layout->hmargin, + layout->vmargin, + allocation.width + - 2 * layout->hmargin, + allocation.height + - 2 * layout->vmargin); + break; } } + cairo_destroy(cr); cairo_surface_destroy(surface); } @@ -389,9 +376,19 @@ launcher_redraw_handler(struct widget *widget, void *data) struct launcher *launcher = data; cairo_surface_t *surface; struct rectangle allocation; + struct rectangle layout_allocation; cairo_t *cr; - surface = window_get_surface(launcher->homescreen->window); + widget_get_allocation(widget, &allocation); + widget_get_allocation(launcher->layout->homescreen->widget, + &layout_allocation); + + /* avoid drawing out of bounding. */ + if (allocation.x <= (0 - allocation.width) || + allocation.x > layout_allocation.width) + return; + + surface = window_get_surface(launcher->layout->homescreen->window); cr = cairo_create(surface); widget_get_allocation(widget, &allocation); @@ -414,6 +411,104 @@ launcher_redraw_handler(struct widget *widget, void *data) } static void +layout_redraw_handler(struct widget *widget, void *data) +{ + struct layout *layout = data; + struct launcher *launcher; + struct rectangle allocation; + const int rows = 3, columns = 4, icon_width = launcher_size, + icon_height = launcher_size; + int x, y, i, width, height, vpadding, hpadding; + + if (layout->showing != 1) + return; + + widget_get_allocation(widget, &allocation); + + width = allocation.width - columns * icon_width; + /* width between icons */ + hpadding = width / (columns - 1); + + height = allocation.height - rows * icon_height; + vpadding = height / (rows - 1); + + x = allocation.x; + y = allocation.y; + i = 0; + + wl_list_for_each(launcher, &layout->launcher_list, link) { + widget_set_allocation(launcher->widget, x + layout->offset, + y, icon_width, icon_height); + x += icon_width + hpadding; + i++; + if (i == columns) { + x = allocation.x; + y += icon_height + vpadding; + i = 0; + } + } + + if (layout->offset < 0 && layout->link.next != layout->layout_list) { + /* need to draw right layout */ + x = allocation.x + layout->offset + + allocation.width + 2 * layout->hmargin; + y = allocation.y; + i = 0; + + layout = __wl_container_of(layout->link.next, layout, link); + + /* add background width */ + wl_list_for_each(launcher, &layout->launcher_list, link) { + if (x < allocation.width + 2 * layout->hmargin) { + /* show icon */ + widget_set_allocation(launcher->widget, x, y, + icon_width, icon_height); + } else { + /* set icon out--see launcher_redraw_handler */ + widget_set_allocation(launcher->widget, + 0, 0, 0, 0); + } + x += icon_width + hpadding; + i++; + if (i == columns) { + x = allocation.x + layout->offset + + allocation.width + 2 * layout->hmargin; + y += icon_height + vpadding; + i = 0; + } + } + } else if (layout->offset > 0 && + layout->link.prev != layout->layout_list) { + /* need to draw left layout */ + width = allocation.x + layout->offset - 2 * layout->hmargin; + x = width - allocation.width; + y = allocation.y; + i = 0; + + layout = __wl_container_of(layout->link.prev, layout, link); + + /* add layout width */ + wl_list_for_each(launcher, &layout->launcher_list, link) { + if(x > -icon_width) { + /* show icon */ + widget_set_allocation(launcher->widget, x, y, + icon_width, icon_height); + } else { + widget_set_allocation(launcher->widget, + 0, 0, 0, 0); + } + x += icon_width + hpadding; + i++; + if (i == columns) { + x = width - allocation.width; + y += icon_height + vpadding; + i = 0; + } + } + } +} + +static void tablet_shell_add_layout(struct tablet *tablet) { fprintf(stderr, "add layout\n"); @@ -441,17 +536,25 @@ tablet_shell_add_layout(struct tablet *tablet) layout->layout_list = &homescreen->layout_list; wl_list_insert(homescreen->layout_list.prev, &layout->link); + widget_set_redraw_handler(layout->widget, + layout_redraw_handler); } static void -tablet_shell_add_launcher(struct tablet *tablet, +layout_add_launcher(struct tablet *tablet, const char *icon, const char *path) { struct launcher *launcher; + struct layout *layout = NULL; struct homescreen *homescreen = tablet->homescreen; + wl_list_for_each(layout, &homescreen->layout_list, link) { + } + /* find the last layout */ + layout = __wl_container_of(layout->link.prev, layout, link); + launcher = malloc(sizeof *launcher); - launcher->path = strdup(path); + memset(launcher, 0, sizeof *launcher); launcher->icon = load_cairo_surface(icon); if ( !launcher->icon || cairo_surface_status (launcher->icon) != CAIRO_STATUS_SUCCESS) { @@ -459,9 +562,13 @@ tablet_shell_add_launcher(struct tablet *tablet, free(launcher); return; } + launcher->path = strdup(path); - launcher->homescreen = homescreen; - launcher->widget = widget_add_widget(homescreen->widget, launcher); + launcher->layout = layout; + + wl_list_insert(layout->launcher_list.prev, &launcher->link); + + launcher->widget = widget_add_widget(layout->widget, launcher); widget_set_enter_handler(launcher->widget, launcher_enter_handler); widget_set_leave_handler(launcher->widget, @@ -470,8 +577,6 @@ tablet_shell_add_launcher(struct tablet *tablet, launcher_button_handler); widget_set_redraw_handler(launcher->widget, launcher_redraw_handler); - - wl_list_insert(&homescreen->launcher_list, &launcher->link); } static void @@ -484,7 +589,7 @@ launcher_section_done(void *data) return; } - tablet_shell_add_launcher(tablet, key_launcher_icon, key_launcher_path); + layout_add_launcher(tablet, key_launcher_icon, key_launcher_path); free(key_launcher_icon); key_launcher_icon = NULL; -- 1.7.11 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel