[PATCH 16/19] tablet-shell: Improve the sliding effect.
ning.tang at intel.com
ning.tang at intel.com
Mon Sep 24 19:40:01 PDT 2012
From: Ning Tang <ning.tang at 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.tang at 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
More information about the wayland-devel
mailing list