~sircmpwn/casa

fa510a6240a7fca08a8b5da9e940f900855400e3 — Gy├Ârgy Kurucz 6 months ago a31ea89 master
Implement tap gesture.
4 files changed, 64 insertions(+), 13 deletions(-)

M include/surface.h
M src/input.c
M src/render.c
M src/surface.c
M include/surface.h => include/surface.h +6 -1
@@ 30,7 30,7 @@ enum casa_surface_state {

struct casa_drag_integrator {
	uint32_t touchpoints;
	float integ[2];
	float integ[2], start[2];
};

enum casa_animation_kind {


@@ 75,6 75,8 @@ struct casa_surface {
	float scroll_offset; // (-infinity, idle_offset]
	struct casa_drag_integrator drag_integrator;
	struct casa_animation scroll_offset_anim;

	int icon_size;
};

struct casa_surface_output {


@@ 94,4 96,7 @@ void casa_surface_touch_down(struct casa_surface *surf, int32_t time);
void casa_surface_touch_up(struct casa_surface *surf, int32_t time,
		const float vel[static 2]);

void casa_surface_get_icon_pos(const struct casa_surface *surf,
		int row, int col, float pos[static 2]);

#endif

M src/input.c => src/input.c +5 -1
@@ 53,7 53,11 @@ wl_touch_down(void *data, struct wl_touch *wl_touch,

	surf->drag_integrator.touchpoints++;

	casa_surface_touch_down(surf, time);
	if (surf->drag_integrator.touchpoints == 1) {
		surf->drag_integrator.start[0] = tp->cur[0];
		surf->drag_integrator.start[1] = tp->cur[1];
		casa_surface_touch_down(surf, time);
	}
	casa_surface_schedule_frame(surf);
}


M src/render.c => src/render.c +6 -10
@@ 17,11 17,7 @@ static void
render_icons(struct casa_surface *surface,
		struct casa_buffer *buffer, float progress, int y_offs)
{
	const int width = 128, height = 128;
	const int nrows = 16, ncols = 4;
	const int gutter = 32;
	int x_margin = (((buffer->width - gutter * 2) / ncols) - width) / 2;
	int y_margin = 32;

	float projection[9], matrix[9], transposition[9];
	const struct casa_shaders *shaders = &surface->casa->shaders;


@@ 53,13 49,13 @@ render_icons(struct casa_surface *surface,

	for (int row = 0; row < nrows; ++row) {
		for (int col = 0; col < ncols; ++col) {
			int x = gutter + x_margin + col * (width + x_margin * 2);
			int y = gutter * 2 + row * (height + y_margin);
			float icon_pos[2];
			casa_surface_get_icon_pos(surface, row, col, icon_pos);
			struct box box = {
				.x = x,
				.y = buffer->height - height - (y + y_offs),
				.width = width,
				.height = height,
				.x = icon_pos[0],
				.y = buffer->height - surface->icon_size - (icon_pos[1] + y_offs),
				.width = surface->icon_size,
				.height = surface->icon_size,
			};
			matrix_project_box(matrix, &box, 0, projection);
			matrix_transpose(transposition, matrix);

M src/surface.c => src/surface.c +47 -1
@@ 1,5 1,6 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <wayland-client.h>
#include "buffers.h"


@@ 15,6 16,7 @@ const int32_t anim_target_duration = 200;
const float gesture_completion_threshold = 0.25;
const float kinetic_scrolling_friction = 0.01; // pixel / msec^2
const float kinetic_scrolling_max_v = 5.0; // pixel / msec
const float gesture_tap_max_distance_squared = 10.0 * 10.0; // pixel^2

static void
casa_surface_drag_get(const struct casa_surface *surf, float off[static 2])


@@ 33,6 35,34 @@ casa_surface_drag_get(const struct casa_surface *surf, float off[static 2])
	}
}

void
casa_surface_get_icon_pos(const struct casa_surface *surf,
		int row, int col, float pos[static 2])
{
	const int width = surf->icon_size, height = surf->icon_size;
	const int ncols = 4;
	const int gutter = 32;
	int x_margin = (((surf->width * surf->scale - gutter * 2) / ncols) - width) / 2;
	int y_margin = 32;

	pos[0] = gutter + x_margin + col * (width + x_margin * 2);
	pos[1] = gutter * 2 + row * (height + y_margin);
}

static void
casa_surface_get_icon_at(const struct casa_surface *surf,
		const float pos[static 2], int *row, int *col)
{
	const int width = surf->icon_size, height = surf->icon_size;
	const int ncols = 4;
	const int gutter = 32;
	int x_margin = (((surf->width * surf->scale - gutter * 2) / ncols) - width) / 2;
	int y_margin = 32;

	*col = (pos[0] - gutter - x_margin) / (width + x_margin * 2);
	*row = (pos[1] - gutter * 2) / (height + y_margin);
}

static void
wl_surface_enter(void *data,
		struct wl_surface *wl_surface,


@@ 143,6 173,8 @@ casa_surface_create(struct casa_state *state, struct wl_output *output)
	surf->casa = state;
	wl_list_init(&surf->outputs);

	surf->icon_size = 128; // TODO: scale this based on something...

	surf->idle_offset = 256; // TODO: scale this based on something...
	surf->scroll_offset = surf->idle_offset;
	surf->state = CASA_SURFACE_IDLE;


@@ 231,7 263,11 @@ casa_surface_state_progress(struct casa_surface *surf, int32_t time,
	if (surf->drag_integrator.touchpoints > 0) {
		float off[2];
		casa_surface_drag_get(surf, off);
		*y_offs = fmin(surf->scroll_offset + off[1], surf->idle_offset);
		if (vec2_dot(off, off) > gesture_tap_max_distance_squared) {
			*y_offs = fmin(surf->scroll_offset + off[1], surf->idle_offset);
		} else {
			*y_offs = surf->scroll_offset;
		}
	} else if (anim->kind != CASA_ANIMATION_NONE) {
		if (anim->time_end > time) {
			*y_offs = casa_animation_val(anim, time);


@@ 272,6 308,16 @@ void
casa_surface_touch_up(struct casa_surface *surf, int32_t time,
		const float vel[static 2])
{
	struct casa_drag_integrator *di = &surf->drag_integrator;
	if (vec2_dot(di->integ, di->integ) <= gesture_tap_max_distance_squared) {
		// tap gesture
		float tap[2] = { di->start[0], di->start[1] - surf->scroll_offset };
		int row, col;
		casa_surface_get_icon_at(surf, tap, &row, &col);
		fprintf(stderr, "tap gesture @(%f %f) @(%d %d)\n", tap[0], tap[1], row, col);
		return;
	}

	surf->scroll_offset += surf->drag_integrator.integ[1];
	surf->scroll_offset = fmin(surf->scroll_offset, surf->idle_offset);