[PATCH 03/19] tablet-shell: break the connection between launcher and homescreen.

ning.tang at intel.com ning.tang at intel.com
Mon Sep 24 19:39:48 PDT 2012


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 <ning.tang at intel.com>
---
 clients/tablet-shell.c | 135 ++++++++++++++++++++++++++++++++++---------------
 weston-tablet.ini      |   3 ++
 2 files changed, 97 insertions(+), 41 deletions(-)

diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index c4ec5e7..10a5ba1 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);
 		}
 	}
 
@@ -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,58 @@ 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 */
+	if (key_layout_columns > 1)
+		hpadding = width / (key_layout_columns - 1);
+	else
+		hpadding = 0;
+	height = allocation.height - key_layout_rows * icon_height;
+	if (key_layout_rows > 1)
+		vpadding = height / (key_layout_rows - 1);
+	else
+		vpadding = 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 +472,30 @@ 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;
 
+	/* find the last layout */
+	layout = __wl_container_of(homescreen->layout_list.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) {
@@ -451,9 +503,13 @@ tablet_shell_add_launcher(struct tablet *tablet,
 		free(launcher);
 		return;
 	}
+	launcher->path = strdup(path);
+
+	launcher->layout = layout;
 
-	launcher->homescreen = homescreen;
-	launcher->widget = widget_add_widget(homescreen->widget, launcher);
+	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 +518,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 +530,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 +581,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.12.1



More information about the wayland-devel mailing list