[PATCH 06/14] tablet-shell: add trash function when dragging launcher icon.

tecton69 at gmail.com tecton69 at gmail.com
Tue Aug 21 04:49:20 PDT 2012


From: Ning Tang <ning.tang at intel.com>

Determine whether to accpet the data by the allocation of trash area. If
the icon is in it, then drop event will delete either the icon image as
well as tag in ini file.

 Signed-off-by: Ning Tang <tecton69 at gmail.com>

---
 clients/tablet-shell.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++-
 weston-tablet.ini      |   1 +
 2 files changed, 151 insertions(+), 3 deletions(-)

diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index eaaa8d7..860bba8 100644
--- a/clients/tablet-shell.c
+++ b/clients/tablet-shell.c
@@ -103,17 +103,22 @@ 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 char *key_trash_image;
 /* launcher drag */
 struct launcher *gl_launcher_drag = NULL;
 static int launcher_size;
 static int key_layout_rows;
 static int key_layout_columns;
 static int layout_moving;
+/* trash parameters */
+static cairo_surface_t *trash_surface = NULL;
+struct rectangle *trash_allocation = NULL;
 
 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 },
+	{ "trash-image", CONFIG_KEY_STRING, &key_trash_image },
 	{ "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 },
@@ -175,6 +180,49 @@ paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
 	}
 }
 
+/*simple draw trash function*/
+static void
+homescreen_draw_trash(void *data, int x, int y)
+{
+	cairo_t *cr;
+	cairo_surface_t *surface;
+	struct homescreen *homescreen = data;
+
+	if (key_trash_image) {
+		if (!trash_surface) {
+			trash_surface = load_cairo_surface(key_trash_image);
+		}
+	} else {
+		trash_surface = NULL;
+	}
+
+	if (!trash_surface) {
+		fprintf(stderr, "no trash image.\n");
+		return;
+	}
+
+	// set up trash allocation
+	if (!trash_allocation) {
+		trash_allocation = malloc(sizeof *trash_allocation);
+		trash_allocation->x = x;
+		trash_allocation->y = y;
+		trash_allocation->width =
+			cairo_image_surface_get_width(trash_surface);
+		trash_allocation->height =
+			cairo_image_surface_get_height(trash_surface);
+	}
+	surface = window_get_surface(homescreen->window);
+	cr = cairo_create(surface);
+
+	cairo_set_source_surface(cr, trash_surface,
+				 trash_allocation->x,
+				 trash_allocation->y);
+	cairo_paint(cr);
+
+	cairo_destroy(cr);
+	cairo_surface_destroy(surface);
+}
+
 static void
 homescreen_draw(struct widget *widget, void *data)
 {
@@ -203,6 +251,13 @@ homescreen_draw(struct widget *widget, void *data)
 		}
 	}
 
+	/* draw trash if dragging*/
+	if(gl_launcher_drag && gl_launcher_drag->widget) {
+		homescreen_draw_trash(homescreen,
+				      allocation.width * 0.6,
+				      allocation.height * 0.6);
+	}
+
 	cairo_destroy(cr);
 	cairo_surface_destroy(surface);
 }
@@ -404,17 +459,83 @@ launcher_motion_handler(struct widget *widget, struct input *input,
 	return CURSOR_HAND1;
 }
 
+static int
+layout_delete_launcher(struct launcher *launcher) {
+	char *config_file = config_file_path("weston-tablet.ini");
+	FILE *fp;
+	char line[512];
+	uint32_t found_pos = 0;
+	uint32_t next_pos = 0;
+	uint32_t end_length = 0;
+	uint32_t layout_num = launcher->layout->index;
+	uint32_t launcher_num = launcher->index;
+
+	fp = fopen(config_file, "r");
+	if (fp == NULL) {
+		fprintf(stderr, "couldn't open %s.\n", config_file);
+		return -1;
+	}
+	while (fgets(line, sizeof line, fp)) {
+		if (strcmp("[layout]\n", line) == 0)
+			layout_num--;
+		if (layout_num == 0 && strcmp("[launcher]\n", line) == 0) {
+			launcher_num--;
+			if (launcher_num == 0) {
+				found_pos = ftell(fp) - 11;
+				break;
+			}
+		}
+	}
+	fseek(fp, found_pos, SEEK_SET);
+	if (!fread(line, 1, 511, fp))
+	{
+		fprintf(stderr, "read ini file error.\n");
+	}
+	char *next = strchr(line + 10, '[');
+	next_pos = next - line + found_pos;
+
+	char *start_content = malloc(sizeof (char) * (found_pos + 1));
+	fseek(fp, 0, SEEK_END);
+	end_length = ftell(fp) - next_pos;
+	char *end_content = malloc(sizeof (char) * (end_length + 1));
+	if (!start_content || !end_content) {
+		fprintf(stderr, "Not enough memory when changing ini file.\n");
+		return -1;
+	}
+	fseek(fp, 0, SEEK_SET);
+	if (!fread(start_content, 1, found_pos, fp))
+		fprintf(stderr, "read ini file error.\n");
+	fseek(fp, next_pos, SEEK_SET);
+	if (!fread(end_content, 1, end_length, fp))
+		fprintf(stderr, "read ini file error.\n");
+	fclose(fp);
+	fp = fopen(config_file, "w");
+	fwrite(start_content, found_pos, 1, fp);
+	fwrite(end_content, end_length, 1, fp);
+	free(start_content);
+	free(end_content);
+	fclose(fp);
+	printf("launcher deleted.\n");
+	return 1;
+}
 static void
 launcher_data_handler(struct window *window,
 		      struct input *input,
 		      float x, float y, const char **types, void *data)
 {
-	if (!types)
+	if (!types || !trash_allocation)
 		return;
 	if (strcmp(types[0], "application/tablet-launcher") != 0) {
 		return;
 	}
-	input_accept(input, types[0]);
+	if (x > trash_allocation->x&&
+	    x < trash_allocation->x + trash_allocation->width &&
+	    y > trash_allocation->y &&
+	    y < trash_allocation->y + trash_allocation->height) {
+		input_accept(input, NULL);
+	} else {
+		input_accept(input, types[0]);
+	}
 }
 
 static void
@@ -433,7 +554,31 @@ launcher_drop_handler(struct window *window, struct input *input,
 
 	launcher->dragging = 0;
 	launcher->pressed = 0;
-	gl_launcher_drag = NULL;
+
+	if (x > trash_allocation->x &&
+	    x < trash_allocation->x + trash_allocation->width &&
+	    y > trash_allocation->y &&
+	    y < trash_allocation->y + trash_allocation->height) {
+		if (layout_delete_launcher(launcher)) {
+			wl_list_remove(&launcher->link);
+			widget_destroy(launcher->widget);
+			launcher->widget = NULL;
+			free((char*)launcher->path);
+			cairo_surface_destroy(launcher->icon);
+			wl_data_source_destroy(launcher->data_source);
+			wl_surface_destroy(launcher->drag_surface);
+			cairo_surface_destroy(launcher->translucent);
+			cairo_surface_destroy(launcher->opaque);
+			int i = 1;
+			wl_list_for_each(temp_launcher,
+					 &layout->launcher_list, link) {
+				temp_launcher->index = i++;
+			}
+			window_schedule_redraw(layout->homescreen->window);
+		}
+	} else {
+		gl_launcher_drag = NULL;
+	}
 	window_schedule_redraw(launcher->layout->homescreen->window);
 }
 
@@ -900,6 +1045,7 @@ tablet_shell_add_layout(struct tablet *tablet)
 
 	/* let layout know number of layouts */
 	layout->layout_list = &homescreen->layout_list;
+	layout->index = wl_list_length(layout->layout_list);
 
 	wl_list_insert(homescreen->layout_list.prev, &layout->link);
 	widget_set_button_handler(layout->widget,
@@ -937,6 +1083,7 @@ layout_add_launcher(struct tablet *tablet,
 	launcher->layout = layout;
 
 	wl_list_insert(layout->launcher_list.prev, &launcher->link);
+	launcher->index = wl_list_length(&layout->launcher_list);
 
 	launcher->widget = widget_add_widget(layout->widget, launcher);
 	widget_set_enter_handler(launcher->widget,
diff --git a/weston-tablet.ini b/weston-tablet.ini
index b5239a8..58fd688 100644
--- a/weston-tablet.ini
+++ b/weston-tablet.ini
@@ -7,6 +7,7 @@ animation=zoom
 layout-rows=6
 layout-columns=8
 icon-size=64
+trash-image=/usr/share/weston/trash.png
 
 [layout]
 [launcher]
-- 
1.7.11.5



More information about the wayland-devel mailing list