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);