From f712d04bed78552ef6be68b79e868dc07266a1be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Mon, 14 Jun 2021 21:33:15 +0200 Subject: [PATCH] feat: add cursor functions --- image-viewer/include/cursor.h | 37 +++++++++++++ image-viewer/src/cursor.c | 98 +++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 image-viewer/include/cursor.h create mode 100644 image-viewer/src/cursor.c diff --git a/image-viewer/include/cursor.h b/image-viewer/include/cursor.h new file mode 100644 index 0000000000000000000000000000000000000000..2304d8be87ac6dde4c43c6bc6f6f860424f4b787 --- /dev/null +++ b/image-viewer/include/cursor.h @@ -0,0 +1,37 @@ +#ifndef __CURSOR_H__ +#define __CURSOR_H__ + +#include "display_utils.h" +#include "image.h" +#include +#include + +#define CURSOR_SIZE 10 + +typedef struct { + uint16_t x; + uint16_t y; + + bool shown; + time_t shown_at; + + display_pixel_t previous_display_data[CURSOR_SIZE * 2 - 1]; +} cursor_t; + +typedef enum { + UP, + LEFT, + DOWN, + RIGHT, +} direction_t; + +const display_pixel_t CURSOR_COLOR = {.fields = {.r = (uint8_t)DISPLAY_MAX_RED, .g = 0, .b = 0}}; + +cursor_t cursor_create(); +void cursor_center(cursor_t *cursor, image_region_t *region); +void cursor_move(cursor_t *cursor, image_region_t *region, direction_t direction, uint8_t amount); + +void cursor_show(cursor_t *cursor, display_t *display); +void cursor_hide(cursor_t *cursor, display_t *display); + +#endif // __CURSOR_H__ diff --git a/image-viewer/src/cursor.c b/image-viewer/src/cursor.c new file mode 100644 index 0000000000000000000000000000000000000000..69f997699168d8979b3f287e9faf7a08a2a019cb --- /dev/null +++ b/image-viewer/src/cursor.c @@ -0,0 +1,98 @@ +#include "cursor.h" +#include "display_utils.h" +#include "image.h" + +cursor_t cursor_create() { + cursor_t cursor = { + .x = 0, + .y = 0, + .shown = false, + .shown_at = 0, + }; + + return cursor; +} + +void cursor_center(cursor_t *cursor, image_region_t *region) { + cursor->x = region->x + region->width / 2; + cursor->y = region->y + region->height / 2; +} + +void cursor_move(cursor_t *cursor, image_region_t *region, direction_t direction, uint8_t amount) { + uint16_t x = cursor->x, y = cursor->y; + + switch (direction) { + case LEFT: + x -= amount; + break; + case RIGHT: + x += amount; + break; + case UP: + y -= amount; + break; + case DOWN: + y += amount; + break; + } + + if (x < region->x) { + x = region->x; + } else if (x > region->x + region->width - 1) { + x = region->x + region->width - 1; + } + + if (y < region->y) { + y = region->y; + } else if (y > region->y + region->height - 1) { + y = region->y + region->height - 1; + } + + cursor->x = x; + cursor->y = y; +} + +void cursor_show(cursor_t *cursor, display_t *display) { + cursor_hide(cursor, display); + cursor->shown_at = time(NULL); + cursor->shown = true; + + uint16_t base_x = cursor->x; + uint16_t base_y = cursor->x; + + uint16_t first_x = base_x - CURSOR_SIZE / 2; + uint16_t first_y = base_y - CURSOR_SIZE / 2; + + for (int i = 0; i < CURSOR_SIZE; i++) { + uint16_t x = first_x + i; + uint16_t y = first_y + i; + + cursor->previous_display_data[i] = display_get_pixel(display, base_x, y); + cursor->previous_display_data[i + CURSOR_SIZE] = display_get_pixel(display, x, base_y); + + display_set_pixel(display, base_x, y, CURSOR_COLOR); + display_set_pixel(display, x, base_y, CURSOR_COLOR); + } +} + +void cursor_hide(cursor_t *cursor, display_t *display) { + if (!cursor->shown) { + return; + } + + uint16_t base_x = cursor->x; + uint16_t base_y = cursor->x; + + uint16_t first_x = base_x - CURSOR_SIZE / 2; + uint16_t first_y = base_y - CURSOR_SIZE / 2; + + for (int i = 0; i < CURSOR_SIZE; i++) { + uint16_t x = first_x + i; + uint16_t y = first_y + i; + + display_set_pixel(display, base_x, y, cursor->previous_display_data[i]); + display_set_pixel(display, x, base_y, cursor->previous_display_data[i + CURSOR_SIZE]); + } + + cursor->shown = false; +}