Animate transitions for zoom focus point change.

Handle the transition when focus changes from text cursor to
mouse pointer or vice versa.
Scott Moreau 13 years ago committed by Kristian Høgsberg
parent 5b72a4d21d
commit 8dacaaba1b
  1. 198
      src/compositor.c
  2. 15
      src/compositor.h
  3. 5
      src/shell.c

@ -1633,7 +1633,7 @@ notify_motion(struct wl_seat *seat, uint32_t time, wl_fixed_t x, wl_fixed_t y)
if (output->zoom.active &&
pixman_region32_contains_point(&output->region,
ix, iy, NULL))
weston_output_update_zoom(output, x, y, ZOOM_FOCUS_POINTER);
weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
weston_device_repick(seat);
interface = seat->pointer->grab->interface;
@ -2783,9 +2783,11 @@ weston_text_cursor_position_notify(struct weston_surface *surface,
pixman_region32_contains_point(&output->region,
wl_fixed_to_int(global_x),
wl_fixed_to_int(global_y),
NULL))
weston_output_update_zoom(output, global_x, global_y,
ZOOM_FOCUS_TEXT);
NULL)) {
output->zoom.text_cursor.x = global_x;
output->zoom.text_cursor.y = global_y;
weston_output_update_zoom(output, ZOOM_FOCUS_TEXT);
}
}
static void
@ -2815,71 +2817,178 @@ weston_zoom_frame_z(struct weston_animation *animation,
}
static void
weston_zoom_transition(struct weston_output *output)
weston_zoom_frame_xy(struct weston_animation *animation,
struct weston_output *output, uint32_t msecs)
{
if (output->zoom.level != output->zoom.spring_z.current) {
output->zoom.spring_z.target = output->zoom.level;
if (wl_list_empty(&output->zoom.animation_z.link)) {
output->zoom.animation_z.frame_counter = 0;
wl_list_insert(output->animation_list.prev,
&output->zoom.animation_z.link);
}
wl_fixed_t x, y;
if (animation->frame_counter <= 1)
output->zoom.spring_xy.timestamp = msecs;
weston_spring_update(&output->zoom.spring_xy, msecs);
x = output->zoom.from.x - ((output->zoom.from.x - output->zoom.to.x) *
output->zoom.spring_xy.current);
y = output->zoom.from.y - ((output->zoom.from.y - output->zoom.to.y) *
output->zoom.spring_xy.current);
output->zoom.current.x = x;
output->zoom.current.y = y;
if (weston_spring_done(&output->zoom.spring_xy)) {
output->zoom.spring_xy.current = output->zoom.spring_xy.target;
output->zoom.current.x =
(output->zoom.type == ZOOM_FOCUS_POINTER) ?
output->compositor->seat->pointer.x :
output->zoom.text_cursor.x;
output->zoom.current.y =
(output->zoom.type == ZOOM_FOCUS_POINTER) ?
output->compositor->seat->pointer.y :
output->zoom.text_cursor.y;
wl_list_remove(&animation->link);
wl_list_init(&animation->link);
}
output->dirty = 1;
weston_output_damage(output);
}
WL_EXPORT void
weston_output_update_zoom(struct weston_output *output,
wl_fixed_t x,
wl_fixed_t y,
uint32_t type)
static void
zoom_area_center_from_pointer(struct weston_output *output,
wl_fixed_t *x, wl_fixed_t *y)
{
float level = output->zoom.spring_z.current;
wl_fixed_t offset_x = wl_fixed_from_int(output->x);
wl_fixed_t offset_y = wl_fixed_from_int(output->y);
wl_fixed_t w = wl_fixed_from_int(output->current->width);
wl_fixed_t h = wl_fixed_from_int(output->current->height);
*x -= ((((*x - offset_x) / (float) w) - 0.5) * (w * (1.0 - level)));
*y -= ((((*y - offset_y) / (float) h) - 0.5) * (h * (1.0 - level)));
}
static void
weston_output_update_zoom_transform(struct weston_output *output)
{
uint32_t type = output->zoom.type;
float global_x, global_y;
wl_fixed_t x = output->zoom.current.x;
wl_fixed_t y = output->zoom.current.y;
float trans_min, trans_max;
float ratio, level;
level = output->zoom.spring_z.current;
ratio = 1 / level;
if (!output->zoom.active || level > output->zoom.max_level)
return;
output->zoom.type = type;
output->zoom.fx = x;
output->zoom.fy = y;
if (type == ZOOM_FOCUS_POINTER &&
wl_list_empty(&output->zoom.animation_xy.link))
zoom_area_center_from_pointer(output, &x, &y);
global_x = wl_fixed_to_double(x);
global_y = wl_fixed_to_double(y);
output->zoom.trans_x =
(((global_x - output->x) / output->current->width) *
(level * 2)) - level;
((((global_x - output->x) / output->current->width) *
(level * 2)) - level) * ratio;
output->zoom.trans_y =
(((global_y - output->y) / output->current->height) *
(level * 2)) - level;
((((global_y - output->y) / output->current->height) *
(level * 2)) - level) * ratio;
if (type == ZOOM_FOCUS_TEXT) {
ratio = 1 / level;
trans_max = level * 2 - level;
trans_min = -trans_max;
output->zoom.trans_x *= ratio;
output->zoom.trans_y *= ratio;
/* Clip zoom area to output */
if (output->zoom.trans_x > trans_max)
output->zoom.trans_x = trans_max;
else if (output->zoom.trans_x < trans_min)
output->zoom.trans_x = trans_min;
if (output->zoom.trans_y > trans_max)
output->zoom.trans_y = trans_max;
else if (output->zoom.trans_y < trans_min)
output->zoom.trans_y = trans_min;
}
trans_max = level * 2 - level;
trans_min = -trans_max;
static void
weston_zoom_transition(struct weston_output *output, uint32_t type,
wl_fixed_t x, wl_fixed_t y)
{
if (output->zoom.type != type) {
/* Set from/to points and start animation */
output->zoom.spring_xy.current = 0.0;
output->zoom.spring_xy.previous = 0.0;
output->zoom.spring_xy.target = 1.0;
if (output->zoom.trans_x > trans_max)
output->zoom.trans_x = trans_max;
else if (output->zoom.trans_x < trans_min)
output->zoom.trans_x = trans_min;
if (output->zoom.trans_y > trans_max)
output->zoom.trans_y = trans_max;
else if (output->zoom.trans_y < trans_min)
output->zoom.trans_y = trans_min;
if (wl_list_empty(&output->zoom.animation_xy.link)) {
output->zoom.animation_xy.frame_counter = 0;
wl_list_insert(output->animation_list.prev,
&output->zoom.animation_xy.link);
output->zoom.from.x = (type == ZOOM_FOCUS_TEXT) ?
x : output->zoom.text_cursor.x;
output->zoom.from.y = (type == ZOOM_FOCUS_TEXT) ?
y : output->zoom.text_cursor.y;
} else {
output->zoom.from.x = output->zoom.current.x;
output->zoom.from.y = output->zoom.current.y;
}
output->zoom.to.x = (type == ZOOM_FOCUS_POINTER) ?
x : output->zoom.text_cursor.x;
output->zoom.to.y = (type == ZOOM_FOCUS_POINTER) ?
y : output->zoom.text_cursor.y;
output->zoom.current.x = output->zoom.from.x;
output->zoom.current.y = output->zoom.from.y;
output->zoom.type = type;
}
if (output->zoom.level != output->zoom.spring_z.current) {
output->zoom.spring_z.target = output->zoom.level;
if (wl_list_empty(&output->zoom.animation_z.link)) {
output->zoom.animation_z.frame_counter = 0;
wl_list_insert(output->animation_list.prev,
&output->zoom.animation_z.link);
}
}
output->dirty = 1;
weston_output_damage(output);
}
WL_EXPORT void
weston_output_update_zoom(struct weston_output *output, uint32_t type)
{
wl_fixed_t x = output->compositor->seat->pointer.x;
wl_fixed_t y = output->compositor->seat->pointer.y;
zoom_area_center_from_pointer(output, &x, &y);
if (type == ZOOM_FOCUS_POINTER) {
if (wl_list_empty(&output->zoom.animation_xy.link)) {
output->zoom.current.x =
output->compositor->seat->pointer.x;
output->zoom.current.y =
output->compositor->seat->pointer.y;
} else {
output->zoom.to.x = x;
output->zoom.to.y = y;
}
}
if (type == ZOOM_FOCUS_TEXT) {
if (wl_list_empty(&output->zoom.animation_xy.link)) {
output->zoom.current.x = output->zoom.text_cursor.x;
output->zoom.current.y = output->zoom.text_cursor.y;
} else {
output->zoom.to.x = output->zoom.text_cursor.x;
output->zoom.to.y = output->zoom.text_cursor.y;
}
}
weston_zoom_transition(output);
weston_zoom_transition(output, type, x, y);
weston_output_update_zoom_transform(output);
}
WL_EXPORT void
@ -2904,9 +3013,7 @@ weston_output_update_matrix(struct weston_output *output)
magnification = 1 / (1 - output->zoom.spring_z.current);
weston_matrix_init(&camera);
weston_matrix_init(&modelview);
weston_output_update_zoom(output, output->zoom.fx,
output->zoom.fy,
output->zoom.type);
weston_output_update_zoom(output, output->zoom.type);
weston_matrix_translate(&camera, output->zoom.trans_x,
flip * output->zoom.trans_y, 0);
weston_matrix_invert(&modelview, &camera);
@ -2951,10 +3058,15 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
output->zoom.level = 0.0;
output->zoom.trans_x = 0.0;
output->zoom.trans_y = 0.0;
output->zoom.type = ZOOM_FOCUS_POINTER;
weston_spring_init(&output->zoom.spring_z, 250.0, 0.0, 0.0);
output->zoom.spring_z.friction = 1000;
output->zoom.animation_z.frame = weston_zoom_frame_z;
wl_list_init(&output->zoom.animation_z.link);
weston_spring_init(&output->zoom.spring_xy, 250.0, 0.0, 0.0);
output->zoom.spring_xy.friction = 1000;
output->zoom.animation_xy.frame = weston_zoom_frame_xy;
wl_list_init(&output->zoom.animation_xy.link);
output->flags = flags;
weston_output_move(output, x, y);

@ -115,16 +115,25 @@ enum {
ZOOM_FOCUS_TEXT
};
struct weston_fixed_point {
wl_fixed_t x, y;
};
struct weston_output_zoom {
int active;
uint32_t type;
float increment;
float level;
float max_level;
wl_fixed_t fx, fy;
float trans_x, trans_y;
struct weston_animation animation_z;
struct weston_spring spring_z;
struct weston_animation animation_xy;
struct weston_spring spring_xy;
struct weston_fixed_point from;
struct weston_fixed_point to;
struct weston_fixed_point current;
struct weston_fixed_point text_cursor;
};
/* bit compatible with drm definitions. */
@ -633,9 +642,7 @@ void
weston_text_cursor_position_notify(struct weston_surface *surface,
wl_fixed_t x, wl_fixed_t y);
void
weston_output_update_zoom(struct weston_output *output,
wl_fixed_t x, wl_fixed_t y,
uint32_t type);
weston_output_update_zoom(struct weston_output *output, uint32_t type);
void
weston_output_update_matrix(struct weston_output *output);
void

@ -2185,10 +2185,7 @@ do_zoom(struct wl_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
output->zoom.spring_z.target = output->zoom.level;
weston_output_update_zoom(output,
seat->pointer->x,
seat->pointer->y,
ZOOM_FOCUS_POINTER);
weston_output_update_zoom(output, output->zoom.type);
}
}
}

Loading…
Cancel
Save