Files
n_signer/firmware/cyd_esp32_2432s028/main/display.c

161 lines
3.4 KiB
C

#include "display.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "ili9341.h"
#define CHAR_W_SMALL 6
#define CHAR_H_SMALL 8
#define CHAR_W_LARGE 12
#define CHAR_H_LARGE 16
static bool s_inited = false;
static int text_width_px(const char *text, int char_w)
{
if (text == NULL) {
return 0;
}
return (int)strlen(text) * char_w;
}
esp_err_t display_init(void)
{
if (s_inited) {
return ESP_OK;
}
ESP_ERROR_CHECK(ili9341_init());
s_inited = true;
return display_clear(RGB565_BLACK);
}
esp_err_t display_fill_rect(int x, int y, int w, int h, uint16_t color)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
if (w <= 0 || h <= 0) {
return ESP_OK;
}
if (x >= DISPLAY_WIDTH || y >= DISPLAY_HEIGHT) {
return ESP_OK;
}
if (x < 0) {
w += x;
x = 0;
}
if (y < 0) {
h += y;
y = 0;
}
if (x + w > DISPLAY_WIDTH) {
w = DISPLAY_WIDTH - x;
}
if (y + h > DISPLAY_HEIGHT) {
h = DISPLAY_HEIGHT - y;
}
if (w <= 0 || h <= 0) {
return ESP_OK;
}
for (int py = y; py < y + h; ++py) {
for (int px = x; px < x + w; ++px) {
ESP_ERROR_CHECK(ili9341_draw_pixel((uint16_t)px, (uint16_t)py, color));
}
}
return ESP_OK;
}
esp_err_t display_clear(uint16_t color)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
ili9341_fill_screen(color);
return ESP_OK;
}
esp_err_t display_draw_text_small(int x, int y, const char *text, uint16_t fg, uint16_t bg)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
if (text == NULL) {
return ESP_ERR_INVALID_ARG;
}
ili9341_draw_text(x, y, text, fg, bg);
return ESP_OK;
}
esp_err_t display_draw_text(int x, int y, const char *text, uint16_t fg, uint16_t bg)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
if (text == NULL) {
return ESP_ERR_INVALID_ARG;
}
ili9341_draw_text(x, y, text, fg, bg);
return ESP_OK;
}
esp_err_t display_draw_text_centered(int y, const char *text, uint16_t fg, uint16_t bg)
{
int w = text_width_px(text, CHAR_W_LARGE);
int x = (DISPLAY_WIDTH - w) / 2;
if (x < 0) {
x = 0;
}
return display_draw_text(x, y, text, fg, bg);
}
esp_err_t display_draw_text_small_centered(int y, const char *text, uint16_t fg, uint16_t bg)
{
int w = text_width_px(text, CHAR_W_SMALL);
int x = (DISPLAY_WIDTH - w) / 2;
if (x < 0) {
x = 0;
}
return display_draw_text_small(x, y, text, fg, bg);
}
esp_err_t display_draw_text_inverse(int x, int y, const char *text, uint16_t bg, uint16_t fg)
{
return display_draw_text_small(x, y, text, fg, bg);
}
esp_err_t display_draw_button_status(int btn_id, bool pressed)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
const int slot_w = DISPLAY_WIDTH / 3;
const int slot_h = 22;
const int x = btn_id * slot_w;
const int y = DISPLAY_HEIGHT - slot_h;
uint16_t fill = pressed ? RGB565_RED : RGB565_DIM_GRAY;
uint16_t text = RGB565_WHITE;
ESP_ERROR_CHECK(display_fill_rect(x, y, slot_w - 1, slot_h - 1, fill));
char label[8];
snprintf(label, sizeof(label), "D%d", btn_id);
ESP_ERROR_CHECK(display_draw_text_small(x + (slot_w / 2) - 6, y + 7, label, text, fill));
return ESP_OK;
}