> -----Original Message-----
> From: Philipp Brüschweiler [mailto:ble...@gmail.com]
> Sent: Tuesday, August 21, 2012 9:59 PM
> To: tecto...@gmail.com
> Cc: wayland-devel@lists.freedesktop.org; juan.j.z...@linux.intel.com; Tang,
> Ning
> Subject: Re: [PATCH 04/14] tablet-shell: add sliding effect of layout.
> 
> 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.
> 
There was a bug that when I dragged to slide layout, a layout is moved out of 
screen
and the next layout is shown. But the pointer's focus is still on previous 
layout, if
click again without moving the mouse will cause bug.
So here I use input_ungrab() to let pointer find correct focus.

Thanks.

> > +               }
> > +       } 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

Reply via email to