From: Ning Tang <ning.t...@intel.com>

 Use spring effect so that layout smoothly slides now.
 When layout motion or sliding automatically, it will use a spring
 effect to follow cursor. Set the new to_offset when mouse drags or
 layout need to sliding switch. So when frame callback it will change
 allocation. It is aimed to reduce the trailing.
 
 Signed-off-by: Ning Tang <ning.t...@intel.com>
---
 clients/tablet-shell.c | 169 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 111 insertions(+), 58 deletions(-)

diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index 477b1df..f5dec79 100644
--- a/clients/tablet-shell.c
+++ b/clients/tablet-shell.c
@@ -228,6 +228,7 @@ homescreen_draw(struct widget *widget, void *data)
        struct homescreen *homescreen = data;
        cairo_surface_t *surface;
        struct rectangle allocation;
+       struct rectangle layout_rect;
        cairo_t *cr;
        struct layout *layout;
 
@@ -244,13 +245,15 @@ homescreen_draw(struct widget *widget, void *data)
        /* 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);
+                       widget_get_allocation(layout->widget, &layout_rect);
+                       if (layout_rect.width == 0)
+                               widget_set_allocation(layout->widget,
+                                                     layout->hmargin,
+                                                     layout->vmargin,
+                                                     allocation.width
+                                                     - 2 * layout->hmargin,
+                                                     allocation.height
+                                                     - 2 * layout->vmargin);
                }
                layout_draw_indicator(layout,
                                      allocation.height - layout->vmargin,
@@ -355,13 +358,10 @@ launcher_motion_handler(struct widget *widget, struct 
input *input,
        uint32_t serial;
 
        widget_get_allocation(widget, &allocation);
-       widget_set_tooltip(widget, basename(launcher->path),
-                          x, allocation.y + allocation.height);
 
        if (!launcher->dragging && launcher->pressed == 1 &&
            time - launcher->click_time > 600)
        {
-               widget_destroy_tooltip(widget);
                // draging mode
                launcher->focused = 0;
                if (gl_launcher_drag)
@@ -725,7 +725,7 @@ launcher_redraw_handler(struct widget *widget, void *data)
                if (launcher->focused) {
                        cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4);
                        cairo_mask_surface(cr, launcher->icon,
-                                       allocation.x, allocation.y);
+                                          allocation.x, allocation.y);
                }
        }
        cairo_destroy(cr);
@@ -735,18 +735,24 @@ launcher_redraw_handler(struct widget *widget, void *data)
 static void
 layout_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
 {
+       int end = 0;
+       int increament = 0;
        struct layout *layout = data;
        struct rectangle allocation;
 
-       if (abs(layout->offset - layout->to_offset) < layout->s_speed) {
-               /* stop switching */
-               layout->offset = 0;
-               layout->switching = 0;
+       if (callback)
+               wl_callback_destroy(callback);
+       if (layout_moving == 2 &&
+           abs(layout->to_offset - layout->offset) <= 1) {
+               end = 1;
+       } else if ((layout_moving == 1 || layout_moving == -1) &&
+                  abs(layout->offset - layout->to_offset) <= 5) {
+               end = 1;
                widget_get_allocation(layout->homescreen->widget, &allocation);
                if (layout->to_offset) {
                        layout->showing = 0;
                        widget_set_allocation(layout->widget,
-                                             0, 0, 0, 0);
+                                             0, layout->vmargin, 1, 1);
                        layout->active = 0;
                } else {
                        layout->active = 1;
@@ -759,14 +765,25 @@ layout_frame_callback(void *data, struct wl_callback 
*callback, uint32_t time)
                                              layout->vmargin);
                        input_ungrab(layout->homescreen->input);
                }
-       } else if (layout_moving) {
-               layout->offset += layout->switching * layout->s_speed;
+       }
+       if (end) {
+               /* stop switching */
+               layout->offset = layout->to_offset;
+               layout->switching = 0;
+       } else if (layout_moving == 1 || layout_moving == -1) {
+               layout->offset += (layout->to_offset - layout->offset)
+                                 / layout->s_speed;
+               layout->offset += layout->switching * 4;
+       } else if (layout_moving == 2) {
+               increament = layout->to_offset - layout->offset;
+               if (abs(increament) < 10)
+                       layout->offset += increament;
+               else
+                       layout->offset += (increament > 0? 8: -8)
+                                         + increament / 4;
        }
 
        widget_schedule_redraw(layout->widget);
-
-       if (callback)
-               wl_callback_destroy(callback);
 }
 
 static const struct wl_callback_listener layout_listener = {
@@ -780,6 +797,7 @@ layout_redraw_handler(struct widget *widget, void *data)
        struct layout *current = data;
        struct launcher *launcher;
        struct rectangle allocation;
+       struct rectangle screen_allocation;
        const int icon_width = launcher_size, icon_height = launcher_size;
        int x, y, i, width, height, vpadding, hpadding;
        struct wl_callback *callback;
@@ -788,13 +806,16 @@ layout_redraw_handler(struct widget *widget, void *data)
                return;
 
        widget_get_allocation(widget, &allocation);
-       width = allocation.width - key_layout_columns * icon_width;
+       widget_get_allocation(layout->homescreen->widget, &screen_allocation);
+       width = screen_allocation.width - 2 * layout->hmargin
+               - 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;
+       height = screen_allocation.height - 2 * layout->vmargin
+                - key_layout_rows * icon_height;
        if (key_layout_rows > 1)
                vpadding = height / (key_layout_rows - 1);
        else
@@ -805,7 +826,7 @@ layout_redraw_handler(struct widget *widget, void *data)
        i = 0;
 
        wl_list_for_each(launcher, &layout->launcher_list, link) {
-               if (x < allocation.width + 2 * layout->hmargin) {
+               if (x < screen_allocation.width) {
                        widget_set_allocation(launcher->widget, x, y,
                                              icon_width, icon_height);
                } else {
@@ -830,21 +851,25 @@ layout_redraw_handler(struct widget *widget, void *data)
 
 static void
 layout_sliding(struct layout *layout, int offset,
-              int to_offset, int switching)
+              int to_offset, int switching, int hide)
 {
        struct rectangle allocation;
-       widget_get_allocation(layout->widget, &allocation);
+       widget_get_allocation(layout->homescreen->widget, &allocation);
        layout->showing = 1;
-       layout->offset = offset;
+       if (offset != -1)
+               layout->offset = offset;
        if (switching) {
-               layout->switching = switching;
                layout->to_offset = to_offset;
+               layout->switching = layout->to_offset - layout->offset > 0?
+                                   1: -1;
        }
        widget_set_allocation(layout->widget,
                              layout->hmargin,
                              layout->vmargin,
-                             allocation.width,
-                             allocation.height);
+                             hide? 1: allocation.width
+                             - 2 * layout->hmargin,
+                             hide? 1: allocation.height
+                             - 2 * layout->vmargin);
        widget_schedule_redraw(layout->widget);
 }
 
@@ -856,7 +881,7 @@ layout_button_handler(struct widget *widget,
 {
        struct layout *layout;
        struct layout *prev_layout = NULL, *next_layout = NULL;
-       struct layout *show_layout = NULL;
+       struct layout *show_layout = NULL, *backup_layout = NULL;
        int y;
        int width;
        int fast_slide = 0;
@@ -896,24 +921,32 @@ layout_button_handler(struct widget *widget,
                        /* origin hide to show the other */
                        if (fast_slide)
                                layout->offset += (layout->offset > 0) ?
-                                                 -width / 2:width / 2;
+                                                 -width / 2: width / 2;
                        layout_sliding(layout,
-                                      layout->offset,
+                                      -1,
                                       layout->offset > 0 ?
                                       width: -width,
                                       layout->offset > 0 ?
-                                      1: -1);
+                                      1: -1, 0);
 
                        if (layout->offset < 0) {
                                /* move to next */
                                layout_sliding(next_layout,
                                               width + layout->offset,
-                                              0, -1);
+                                              0, -1, 1);
+                               if (prev_layout && prev_layout->switching)
+                                       layout_sliding(prev_layout,
+                                                      -1,
+                                                      -width, -1, 1);
                        } else {
                                /* move to previous */
                                layout_sliding(prev_layout,
                                               -width + layout->offset,
-                                              0, 1);
+                                              0, 1, 1);
+                               if (next_layout && next_layout->switching)
+                                       layout_sliding(next_layout,
+                                                      -1,
+                                                      width, 1, 1);
                        }
                } else {
                        /* back to itself */
@@ -922,21 +955,28 @@ layout_button_handler(struct widget *widget,
                        layout->to_offset = 0;
                        if (fast_slide && layout->offset != 0)
                                layout->offset += (layout->offset > 0)?
-                                                 -width / 2 : width / 2;
+                                                 -width / 2: width / 2;
                        show_layout = (layout->offset < 0)? next_layout :
                                                            prev_layout;
                        if (!show_layout) {
+                               backup_layout = (layout->offset < 0)?
+                                               prev_layout : next_layout;
+                               if (backup_layout && backup_layout->switching)
+                                       layout_sliding(backup_layout,
+                                                      -1,
+                                                      layout->offset > 0 ?
+                                                      width : -width,
+                                                      layout->offset > 0 ?
+                                                      -1: 1, 1);
                                widget_schedule_redraw(layout->widget);
                                return;
                        }
                        layout_sliding(show_layout,
                                       layout->offset > 0 ?
-                                      layout->offset - screen_allocation.width:
-                                      layout->offset + screen_allocation.width,
-                                      layout->offset > 0 ?
-                                      -screen_allocation.width :
-                                      screen_allocation.width,
-                                      layout->offset > 0 ? -1: 1);
+                                      layout->offset - width:
+                                      layout->offset + width,
+                                      layout->offset > 0 ? -width : width,
+                                      layout->offset > 0 ? -1: 1, 1);
                }
                /* update scene */
                widget_schedule_redraw(layout->widget);
@@ -964,26 +1004,40 @@ layout_motion_handler(struct widget *widget, struct 
input *input,
 
        if (layout->pressed)
        {
-               layout->offset += x - layout->last_x;
+               layout_moving = 2;
+               if (layout->switching) {
+                       layout->to_offset += (int)x - layout->last_x;
+                       layout->switching = layout->to_offset - layout->offset >
+                                           0? 1: -1;
+               } else
+                       layout_sliding(layout, -1,
+                                      layout->to_offset + (int)x -
+                                      layout->last_x,
+                                      layout->to_offset - layout->offset > 0?
+                                      1: -1, 0);
                layout->last_x = x;
-               widget_schedule_redraw(layout->widget);
                if (layout->offset < 0 &&
                    layout->link.next != layout->layout_list) {
                        show_layout = __wl_container_of(layout->link.next,
                                                        layout, link);
-                       show_layout->offset = layout->offset +
-                                             screen_allocation.width;
+                       show_layout->to_offset = layout->to_offset +
+                                                screen_allocation.width;
                } else if (layout->offset > 0 &&
                           layout->link.prev != layout->layout_list) {
                        show_layout = __wl_container_of(layout->link.prev,
                                                        layout, link);
-                       show_layout->offset = layout->offset -
-                                             screen_allocation.width;
+                       show_layout->to_offset = layout->to_offset -
+                                                screen_allocation.width;
                }
                if (show_layout) {
-                       layout_sliding(show_layout,
-                                      show_layout->offset,
-                                      0, 0);
+                       if (show_layout->switching)
+                               show_layout->switching = layout->switching;
+                       else
+                               layout_sliding(show_layout,
+                                              -1,
+                                              show_layout->to_offset,
+                                              layout->to_offset -
+                                              layout->offset > 0? 1: -1, 1);
                }
        }
 
@@ -997,8 +1051,9 @@ tablet_shell_add_layout(struct tablet *tablet)
        struct homescreen *homescreen = tablet->homescreen;
        struct rectangle allocation;
        char *index_image;
-       widget_get_allocation(homescreen->widget, &allocation);
 
+       output_get_allocation(display_get_output(tablet->display),
+                             &allocation);
        layout = malloc(sizeof *layout);
        memset(layout, 0, sizeof *layout);
        wl_list_init(&layout->launcher_list);
@@ -1006,14 +1061,12 @@ tablet_shell_add_layout(struct tablet *tablet)
        layout->homescreen = homescreen;
        layout->hmargin = 100;
        layout->vmargin = 50;
-       layout->switching = 0;
-       layout->s_speed = 30;
+       layout->s_speed = 13;
        if (wl_list_empty(&homescreen->layout_list)) {
                layout->active = 1;
                layout->showing = 1;
-       }
-       layout->offset = 0;
-
+       } else
+               layout->offset = allocation.width;
        /* let layout know number of layouts */
        layout->layout_list = &homescreen->layout_list;
        layout->index = wl_list_length(layout->layout_list);
-- 
1.7.12.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to