[PATCH 3/5] tablet-shell: Making the layout draggable and have sliding effect.
tecton69 at gmail.com
tecton69 at gmail.com
Tue Jul 17 02:08:15 PDT 2012
From: Ning Tang <tecton69 at gmail.com>
Use frame callback to move layout and thus making layout move
at a speed. Also button and motion function will record the offset.
Signed-off-by: Li Chen <cl.zhejiang.china at gmail.com>
Signed-off-by: Yi Yuan <harryyuan910702 at gmail.com>
Signed-off-by: Ning Tang <tecton69 at gmail.com>
---
clients/tablet-shell.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 165 insertions(+), 2 deletions(-)
diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index 54fb5b0..0a9e868 100644
--- a/clients/tablet-shell.c
+++ b/clients/tablet-shell.c
@@ -411,14 +411,39 @@ launcher_redraw_handler(struct widget *widget, void *data)
}
static void
+layout_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
+{
+ struct layout *layout = data;
+
+ if (abs(layout->offset) < layout->s_speed) {
+ /* stop switching */
+ layout->offset = 0;
+ layout->switching = 0;
+ } else {
+ layout->offset += layout->switching * layout->s_speed;
+ }
+
+ widget_schedule_redraw(layout->widget);
+
+ if (callback)
+ wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener layout_listener = {
+ layout_frame_callback
+};
+
+static void
layout_redraw_handler(struct widget *widget, void *data)
{
struct layout *layout = data;
+ struct layout *current = data;
struct launcher *launcher;
struct rectangle allocation;
const int rows = 3, columns = 4, icon_width = launcher_size,
icon_height = launcher_size;
int x, y, i, width, height, vpadding, hpadding;
+ struct wl_callback *callback;
if (layout->showing != 1)
return;
@@ -472,7 +497,7 @@ layout_redraw_handler(struct widget *widget, void *data)
i++;
if (i == columns) {
x = allocation.x + layout->offset
- + allocation.width + 2 * layout->hmargin;
+ + allocation.width + 2 * layout->hmargin;
y += icon_height + vpadding;
i = 0;
}
@@ -506,6 +531,140 @@ layout_redraw_handler(struct widget *widget, void *data)
}
}
}
+
+ if (current->switching) {
+ callback = wl_surface_frame(window_get_wl_surface(
+ current->homescreen->window));
+ wl_callback_add_listener(callback, &layout_listener, current);
+ }
+}
+
+static void
+layout_button_handler(struct widget *widget,
+ struct input *input, uint32_t time,
+ uint32_t button,
+ enum wl_pointer_button_state state, void *data)
+{
+ struct layout *layout;
+ struct layout *prev_layout = NULL, *next_layout = NULL;
+ struct launcher *launcher;
+ int y;
+ int width;
+ int fast_slide = 0;
+ struct rectangle allocation;
+
+ layout = widget_get_user_data(widget);
+
+ if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
+ layout->pressed = 0;
+
+ /* do offset check to determine switch direction */
+ widget_get_allocation(widget, &allocation);
+ width = allocation.width + layout->hmargin * 2;
+
+ if (time - layout->click_time < 700) {
+ fast_slide = 1;
+ /* less than 0.7 second, also slide layout. */
+ if (layout->offset > 0)
+ layout->offset += width / 2;
+ else if (layout->offset < 0)
+ layout->offset -= width / 2;
+ }
+
+ if (layout->link.next != layout->layout_list)
+ next_layout = __wl_container_of(layout->link.next,
+ layout, link);
+ if (layout->link.prev != layout->layout_list)
+ prev_layout = __wl_container_of(layout->link.prev,
+ layout, link);
+
+ if ((layout->offset < -width / 2 && next_layout != NULL) ||
+ (layout->offset > width / 2 && prev_layout != NULL)) {
+ /* origin hide to show the other */
+ layout->showing = 0;
+ widget_set_allocation(layout->widget, 0, 0, 0, 0);
+ wl_list_for_each(launcher,
+ &layout->launcher_list, link) {
+ widget_set_allocation(launcher->widget,
+ 0, 0, 0, 0);
+ }
+
+ if (layout->offset < 0) {
+ /* move to next */
+ if (fast_slide)
+ layout->offset += (layout->offset > 0)?
+ -width / 2:width / 2;
+ next_layout->offset = width + layout->offset;
+ next_layout->showing = 1;
+ /* switch animation */
+ next_layout->switching = -1;
+ widget_set_allocation(next_layout->widget,
+ layout->hmargin,
+ layout->vmargin,
+ allocation.width,
+ allocation.height);
+ } else {
+ /* move to previous */
+ if (fast_slide)
+ layout->offset += (layout->offset > 0)?
+ -width / 2:width / 2;
+ prev_layout->offset = layout->offset - width;
+ prev_layout->showing = 1;
+ /* switch animation */
+ prev_layout->switching = 1;
+ widget_set_allocation(prev_layout->widget,
+ layout->hmargin,
+ layout->vmargin,
+ allocation.width,
+ allocation.height);
+ }
+ } else {
+ /* back to itself */
+ layout->switching = (layout->offset > 0)? -1 : 1;
+ if (fast_slide && layout->offset != 0)
+ layout->offset += (layout->offset > 0)?
+ -width / 2 : width / 2;
+ if (prev_layout != NULL) {
+ wl_list_for_each(launcher,
+ &prev_layout->launcher_list,
+ link) {
+ widget_set_allocation(launcher->widget,
+ 0, 0, 0, 0);
+ }
+ }
+ if (next_layout != NULL) {
+ wl_list_for_each(launcher,
+ &next_layout->launcher_list,
+ link) {
+ widget_set_allocation(launcher->widget,
+ 0, 0, 0, 0);
+ }
+ }
+ }
+ /* update scene */
+ widget_schedule_redraw(layout->widget);
+ } else if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
+ layout->pressed = 1;
+ layout->click_time = time;
+ /* record first position */
+ input_get_position(input,&layout->last_x, &y);
+ }
+}
+
+static int
+layout_motion_handler(struct widget *widget, struct input *input,
+ uint32_t time, float x, float y, void *data)
+{
+ struct layout *layout = data;
+
+ if (layout->pressed)
+ {
+ layout->offset += x - layout->last_x;
+ layout->last_x = x;
+ widget_schedule_redraw(layout->widget);
+ }
+
+ return CURSOR_LEFT_PTR;
}
static void
@@ -525,7 +684,7 @@ tablet_shell_add_layout(struct tablet *tablet)
layout->hmargin = 100;
layout->vmargin = 50;
layout->switching = 0;
- layout->s_speed = 20;
+ layout->s_speed = 40;
if (wl_list_empty(&homescreen->layout_list))
layout->showing = 1;
else
@@ -536,6 +695,10 @@ tablet_shell_add_layout(struct tablet *tablet)
layout->layout_list = &homescreen->layout_list;
wl_list_insert(homescreen->layout_list.prev, &layout->link);
+ widget_set_button_handler(layout->widget,
+ layout_button_handler);
+ widget_set_motion_handler(layout->widget,
+ layout_motion_handler);
widget_set_redraw_handler(layout->widget,
layout_redraw_handler);
}
--
1.7.11.1
More information about the wayland-devel
mailing list