[PATCH 2/5] tablet-shell: Draw layout and launchers on it.

tecton69 at gmail.com tecton69 at gmail.com
Tue Jul 17 02:06:55 PDT 2012


From: Ning Tang <tecton69 at gmail.com>

Layout add redraw function to set allocation for launchers.

Signed-off-by: Li Chen          <cl.zhejiang.china at gmail.com>
Signed-off-by: Yi Yuan          <harryyuan910702 at gmail.com>
Signed-off-by: Ning Tang        <tecton69 at 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.1



More information about the wayland-devel mailing list