[PATCH 06/14] tablet-shell: add trash function when dragging launcher icon.
Philipp Brüschweiler
blei42 at gmail.com
Tue Aug 21 08:00:34 PDT 2012
On Tue, Aug 21, 2012 at 1:49 PM, <tecton69 at gmail.com> wrote:
> 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;
Why don't you call this function with a struct homescreen* argument?
AFAICS it's only called by you directly.
> +
> + 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);
> + }
Could you do this initialization at startup instead on each redraw?
> + 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;
You test the return value of this function against 0, so you should
return 0 on error, not -1. But I think this function is generally kind
of hacky... And I think it should be moved to shared/config-parser.c
together with the other config handling functions.
> + }
> + 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) {
I think it would be worth it to refactor this comparison into its own
function. Maybe even move it to window.c, as it seems generally
useful.
> + 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
>
> _______________________________________________
> 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