On Tue, Aug 21, 2012 at 1:49 PM, <tecto...@gmail.com> wrote: > From: Ning Tang <ning.t...@intel.com> > > Launcher is totally depend on layout and add layout > redraw function to manage drawing launchers. > > Signed-off-by: Ning Tang <tecto...@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. > + > + 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); > + > 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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel