On Tue, Aug 21, 2012 at 1:49 PM, <tecto...@gmail.com> wrote: > From: Ning Tang <ning.t...@intel.com> > > Use frame callback to enable layout moving, so dragging layout > will cause layout's offset changes. > And redraw function will allocate corresponding positions to launchers. > The allocation of layout won't change until sliding ends. > > Signed-off-by: Ning Tang <tecto...@gmail.com> > > --- > clients/tablet-shell.c | 225 > ++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 224 insertions(+), 1 deletion(-) > > diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c > index 3a0f04c..515d198 100644 > --- a/clients/tablet-shell.c > +++ b/clients/tablet-shell.c > @@ -47,6 +47,7 @@ struct homescreen { > struct window *window; > struct widget *widget; > struct wl_list layout_list; > + struct input *input; > }; > > struct lockscreen { > @@ -60,12 +61,17 @@ struct layout { > struct homescreen *homescreen; > struct wl_list launcher_list; > struct wl_list link; > + int index; > int pressed; > int showing; > int offset; > + int to_offset; > + int last_x; > int hmargin; > int vmargin; > - > + uint32_t click_time; /* ms */ > + int switching; /* 0-no 1-right -1-left*/ > + int s_speed; /* switching speed */ > struct wl_list *layout_list; /* we need know the number of list */ > }; > > @@ -88,6 +94,7 @@ static void layout_section_done(void *data); > static int launcher_size; > static int key_layout_rows; > static int key_layout_columns; > +static int layout_moving; > > static const struct config_key shell_config_keys[] = { > { "lockscreen-icon", CONFIG_KEY_STRING, &key_lockscreen_icon }, > @@ -251,6 +258,7 @@ homescreen_create(struct tablet *tablet) > widget_set_redraw_handler(homescreen->widget, homescreen_draw); > > wl_list_init(&homescreen->layout_list); > + layout_moving = 1; > return homescreen; > } > > @@ -408,13 +416,54 @@ 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; > + struct rectangle allocation; > + > + if (abs(layout->offset - layout->to_offset) < layout->s_speed) { > + /* stop switching */ > + layout->offset = 0; > + layout->switching = 0; > + widget_get_allocation(layout->homescreen->widget, > &allocation); > + if (layout->to_offset) { > + layout->showing = 0; > + widget_set_allocation(layout->widget, > + 0, 0, 0, 0); > + } else { > + widget_set_allocation(layout->widget, > + layout->hmargin, > + layout->vmargin, > + allocation.width - 2 * > + layout->hmargin, > + allocation.height - 2 * > + layout->vmargin); > + input_ungrab(layout->homescreen->input);
Why is this input_ungrab() necessary here? You don't seem to grab the input yourself anywhere. > + } > + } else if (layout_moving) { > + 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 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; > @@ -447,6 +496,174 @@ layout_redraw_handler(struct widget *widget, void *data) > i = 0; > } > } > + > + 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_sliding(struct layout *layout, int offset, > + int to_offset, int switching) > +{ > + struct rectangle allocation; > + widget_get_allocation(layout->widget, &allocation); > + layout->showing = 1; > + layout->offset = offset; > + if (switching) { > + layout->switching = switching; > + layout->to_offset = to_offset; > + } > + widget_set_allocation(layout->widget, > + layout->hmargin, > + layout->vmargin, > + allocation.width, > + allocation.height); > + widget_schedule_redraw(layout->widget); > +} > + > +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 layout *show_layout = NULL; > + int y; > + int width; > + int fast_slide = 0; > + struct rectangle layout_allocation; > + struct rectangle screen_allocation; > + > + layout = widget_get_user_data(widget); > + layout->homescreen->input = input; > + if (state == WL_POINTER_BUTTON_STATE_RELEASED) { > + layout_moving = 1; > + layout->pressed = 0; > + > + /* do offset check to determine switch direction */ > + widget_get_allocation(widget, &layout_allocation); > + widget_get_allocation(layout->homescreen->widget, > + &screen_allocation); > + width = screen_allocation.width; > + > + 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 */ > + if (fast_slide) > + layout->offset += (layout->offset > 0) ? > + -width / 2:width / 2; > + layout_sliding(layout, > + layout->offset, > + layout->offset > 0 ? > + width: -width, > + layout->offset > 0 ? > + 1: -1); > + > + if (layout->offset < 0) { > + /* move to next */ > + layout_sliding(next_layout, > + width + layout->offset, > + 0, -1); > + } else { > + /* move to previous */ > + layout_sliding(prev_layout, > + -width + layout->offset, > + 0, 1); > + } > + } else { > + /* back to itself */ > + layout->switching = (layout->offset > 0)? -1 : 1; > + layout->showing = 1; > + layout->to_offset = 0; > + if (fast_slide && layout->offset != 0) > + layout->offset += (layout->offset > 0)? > + -width / 2 : width / 2; > + show_layout = (layout->offset < 0)? next_layout : > + prev_layout; > + if (!show_layout) { > + 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); > + } > + /* update scene */ > + widget_schedule_redraw(layout->widget); > + } else if (state == WL_POINTER_BUTTON_STATE_PRESSED) { > + layout_moving = 0; > + 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; > + struct layout *show_layout = NULL; > + struct rectangle layout_allocation, screen_allocation; > + > + widget_get_allocation(layout->widget, > + &layout_allocation); > + widget_get_allocation(layout->homescreen->widget, > + &screen_allocation); > + > + if (layout->pressed) > + { > + layout->offset += x - layout->last_x; > + 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; > + } 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; > + } > + if (show_layout) { > + layout_sliding(show_layout, > + show_layout->offset, > + 0, 0); > + } > + } > + > + return CURSOR_LEFT_PTR; > } > > static void > @@ -464,6 +681,8 @@ tablet_shell_add_layout(struct tablet *tablet) > layout->homescreen = homescreen; > layout->hmargin = 100; > layout->vmargin = 50; > + layout->switching = 0; > + layout->s_speed = 30; > if (wl_list_empty(&homescreen->layout_list)) { > layout->showing = 1; > } > @@ -473,6 +692,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.5 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel