[PATCH 03/14] tablet-shell: break the connection between launcher and homescreen.
Tang, Ning
ning.tang at intel.com
Tue Aug 21 19:01:20 PDT 2012
-----Original Message-----
From: Philipp Brüschweiler [mailto:blei42 at gmail.com]
Sent: Tuesday, August 21, 2012 9:34 PM
To: tecton69 at gmail.com
Cc: wayland-devel at lists.freedesktop.org; juan.j.zhao at linux.intel.com; Tang, Ning
Subject: Re: [PATCH 03/14] tablet-shell: break the connection between launcher and homescreen.
On Tue, Aug 21, 2012 at 1:49 PM, <tecton69 at gmail.com> wrote:
> From: Ning Tang <ning.tang at intel.com>
>
> Launcher is totally depend on layout and add layout redraw function to
> manage drawing launchers.
>
> Signed-off-by: Ning Tang <tecton69 at gmail.com>
>
> ---
> clients/tablet-shell.c | 133 +++++++++++++++++++++++++++++++++----------------
> weston-tablet.ini | 3 ++
> 2 files changed, 94 insertions(+), 42 deletions(-)
>
> diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c index
> c4ec5e7..3a0f04c 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;
> };
>
> @@ -63,6 +62,7 @@ struct layout {
> struct wl_list link;
> int pressed;
> int showing;
> + int offset;
> int hmargin;
> int vmargin;
>
> @@ -71,7 +71,6 @@ struct layout {
>
> struct launcher {
> struct widget *widget;
> - struct homescreen *homescreen;
> struct layout *layout;
> cairo_surface_t *icon;
> int focused, pressed;
> @@ -86,11 +85,17 @@ static char *key_launcher_icon; static char
> *key_launcher_path; static void launcher_section_done(void *data);
> static void layout_section_done(void *data);
> +static int launcher_size;
> +static int key_layout_rows;
> +static int key_layout_columns;
>
> static const struct config_key shell_config_keys[] = {
> { "lockscreen-icon", CONFIG_KEY_STRING, &key_lockscreen_icon },
> { "lockscreen", CONFIG_KEY_STRING, &key_lockscreen_background },
> { "homescreen", CONFIG_KEY_STRING, &key_homescreen_background
> },
> + { "layout-rows", CONFIG_KEY_UNSIGNED_INTEGER, &key_layout_rows },
> + { "layout-columns", CONFIG_KEY_UNSIGNED_INTEGER, &key_layout_columns },
> + { "icon-size", CONFIG_KEY_UNSIGNED_INTEGER, &launcher_size },
> };
>
> static const struct config_key launcher_config_keys[] = { @@ -156,9
> +161,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);
> @@ -166,29 +169,16 @@ 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);
> }
> }
>
> @@ -375,7 +365,7 @@ launcher_button_handler(struct widget *widget,
> if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
> launcher_activate(launcher);
> launcher->pressed = 0;
> - } else if (state == WL_POINTER_BUTTON_STATE_PRESSED)
> + } else if (state == WL_POINTER_BUTTON_STATE_PRESSED)
> launcher->pressed = 1; }
>
> @@ -385,12 +375,20 @@ 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);
> - cr = cairo_create(surface);
> -
> 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);
> if (launcher->pressed) {
> allocation.x++;
> allocation.y++;
> @@ -410,12 +408,53 @@ 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 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 - key_layout_columns * icon_width;
> + /* width between icons */
> + hpadding = width / (key_layout_columns - 1);
> +
> + height = allocation.height - key_layout_rows * icon_height;
> + vpadding = height / (key_layout_rows - 1);
It's unlikely, but when rows or columns is set to 1, this results in a division by 0.
Oh, sorry I didn't notice that, I will fix it. Thanks :)
> +
> + x = allocation.x + layout->offset;
> + y = allocation.y;
> + i = 0;
> +
> + wl_list_for_each(launcher, &layout->launcher_list, link) {
> + if (x < allocation.width + 2 * layout->hmargin) {
> + 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 == key_layout_columns) {
> + x = allocation.x + layout->offset;
> + y += icon_height + vpadding;
> + i = 0;
> + }
> + }
> +}
> +
> +static void
> tablet_shell_add_layout(struct tablet *tablet) {
> struct layout *layout;
> struct homescreen *homescreen = tablet->homescreen;
> struct rectangle allocation;
> - char *index_image;
> widget_get_allocation(homescreen->widget, &allocation);
>
> layout = malloc(sizeof *layout); @@ -428,22 +467,31 @@
> tablet_shell_add_layout(struct tablet *tablet)
> if (wl_list_empty(&homescreen->layout_list)) {
> layout->showing = 1;
> }
> + layout->offset = 0;
>
> /* let layout know number of layouts */
> 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,
> - const char *icon, const char *path)
> +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);
Wouldn't it be easier to just do this:
layout = container_of(homescreen->layout_list.prev, struct layout, link);
You are right, it's more efficient, thanks.
> +
> 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) { @@ -451,9 +499,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,
> @@ -462,8 +514,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
> @@ -476,7 +526,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;
> @@ -527,7 +577,6 @@ int main(int argc, char *argv[])
> tablet.homescreen = homescreen_create(&tablet);
> tablet_shell_set_homescreen(tablet.tablet_shell,
> window_get_wl_surface(tablet.homescreen->window));
> - wl_list_init(&tablet.homescreen->launcher_list);
> wl_list_init(&tablet.homescreen->layout_list);
>
> config_file = config_file_path("weston-tablet.ini");
> diff --git a/weston-tablet.ini b/weston-tablet.ini index
> d38b87a..b5239a8 100644
> --- a/weston-tablet.ini
> +++ b/weston-tablet.ini
> @@ -4,6 +4,9 @@
> lockscreen-icon=/usr/share/weston/org.tizen.gallery.png
> lockscreen=/usr/share/backgrounds/gnome/Garden.jpg
> homescreen=/usr/share/backgrounds/gnome/Aqua.jpg
> animation=zoom
> +layout-rows=6
> +layout-columns=8
> +icon-size=64
>
> [layout]
> [launcher]
> --
> 1.7.11.5
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list