176 lines
7.1 KiB
C
176 lines
7.1 KiB
C
#include <stdint.h>
|
|
#include "keypad.h"
|
|
#include "st7735.h"
|
|
#include "asciifont.h"
|
|
#include "ui_menu.h"
|
|
#include "ui_utils.h"
|
|
|
|
#define LIST_STYLE_SELECTED_COLOR_BG ST7735_COLOR565(0x40, 0x40, 0x40)
|
|
#define LIST_STYLE_OFFSET_LEFT 32
|
|
#define UI_HALF_Y (UI_Y + (UI_H / 2))
|
|
#define LIST_PAGE_SIZE (UI_H / font_unifont_8x16->char_height)
|
|
#define LIST_PAGE_SIZE_HALF ((LIST_PAGE_SIZE + 1) / 2)
|
|
#define LIST_ITEM_LEVEL(p) ((p < LIST_PAGE_SIZE_HALF) ? (p) : (LIST_PAGE_SIZE - p - 1))
|
|
#define UI_LIST_OFFSET_X(p) (UI_X + (LIST_STYLE_OFFSET_LEFT * LIST_ITEM_LEVEL(p) / (LIST_PAGE_SIZE_HALF - 1)) + 8)
|
|
#define UI_LIST_OFFSET_Y(p) (UI_Y + (font_unifont_8x16->char_height * p))
|
|
#define UI_LIST_WIDTH(p) (UI_W - (LIST_STYLE_OFFSET_LEFT * LIST_ITEM_LEVEL(p) / (LIST_PAGE_SIZE_HALF - 1)) - 8)
|
|
|
|
#define U8_RESET 255
|
|
/*
|
|
0
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
*/
|
|
static uint16_t get_item_count(uiu_GetStrItemFunc get_item) {
|
|
uint16_t len = 0;
|
|
while (get_item(len).len > 0) {
|
|
len ++;
|
|
}
|
|
return len;
|
|
}
|
|
|
|
static void render_page_number(uint8_t curr, uint8_t total) {
|
|
uint8_t number_str[4] = {0, 0, 0, 0};
|
|
uint8_t scale = 100;
|
|
uint8_t num_pos = 0;
|
|
while (scale > 0) {
|
|
uint8_t num = (curr / scale) % 10;
|
|
scale /= 10;
|
|
if (num == 0 && num_pos == 0) continue;
|
|
number_str[num_pos] = '0' + num;
|
|
num_pos ++;
|
|
}
|
|
uiu_text_area(font_quan_8x8, number_str, 4,
|
|
UI_X, UI_HALF_Y - 1 - font_quan_8x8->char_height - 1,
|
|
font_quan_8x8->char_width * 3, font_quan_8x8->char_height,
|
|
uiu_ALIGN_HCENTER | uiu_ALIGN_VCENTER, ST7735_YELLOW, ST7735_BLACK
|
|
);
|
|
number_str[0] = 0;
|
|
number_str[1] = 0;
|
|
number_str[2] = 0;
|
|
number_str[3] = 0;
|
|
scale = 100;
|
|
num_pos = 0;
|
|
while (scale > 0) {
|
|
uint8_t num = (total / scale) % 10;
|
|
scale /= 10;
|
|
if (num == 0 && num_pos == 0) continue;
|
|
number_str[num_pos] = '0' + num;
|
|
num_pos ++;
|
|
}
|
|
uiu_text_area(font_quan_8x8, number_str, 4,
|
|
UI_X, UI_HALF_Y + 2,
|
|
font_quan_8x8->char_width * 3, font_quan_8x8->char_height,
|
|
uiu_ALIGN_HCENTER | uiu_ALIGN_VCENTER, ST7735_YELLOW, ST7735_BLACK
|
|
);
|
|
}
|
|
|
|
IndexResult iui_list_select(const uint8_t *title, uint32_t len, uiu_GetStrItemFunc get_item, uint16_t init_index) {
|
|
uint16_t item_count = get_item_count(get_item);
|
|
uint16_t pointer = init_index % item_count;
|
|
uint8_t tmp_pointer = U8_RESET;
|
|
uint8_t last_pointer = U8_RESET;
|
|
uint16_t page_start = (pointer / LIST_PAGE_SIZE) * LIST_PAGE_SIZE;
|
|
printf("item count: %u\n", item_count);
|
|
// clear
|
|
ST7735_FillScreen(ST7735_BLACK);
|
|
// render title
|
|
uiu_title(title, len);
|
|
// render line
|
|
ST7735_DrawLine(UI_X, UI_Y + font_unifont_8x16->char_height, LIST_STYLE_OFFSET_LEFT - 1, UI_HALF_Y - 1, ST7735_YELLOW);
|
|
ST7735_DrawLine(UI_X, UI_Y + UI_H - font_unifont_8x16->char_height - 1, LIST_STYLE_OFFSET_LEFT - 1, UI_HALF_Y, ST7735_YELLOW);
|
|
ST7735_FillRectangle(UI_X, UI_HALF_Y - 1, LIST_STYLE_OFFSET_LEFT - 1, 1, ST7735_YELLOW);
|
|
while (1) {
|
|
uint8_t event = kp_query();
|
|
uint8_t et = kp_Type(event);
|
|
uint8_t ev = kp_Value(event);
|
|
// process event
|
|
if (et == kp_ROTATE_RIGHT || et == kp_ROTATE_LEFT) {
|
|
if (et == kp_ROTATE_RIGHT) {
|
|
pointer += ev;
|
|
} else {
|
|
pointer += (0x7FFF / item_count) * item_count;
|
|
pointer -= ev;
|
|
}
|
|
pointer %= item_count;
|
|
if (((pointer / LIST_PAGE_SIZE) * LIST_PAGE_SIZE) != page_start) {
|
|
last_pointer = U8_RESET;
|
|
page_start = ((pointer / LIST_PAGE_SIZE) * LIST_PAGE_SIZE);
|
|
}
|
|
tmp_pointer = U8_RESET;
|
|
printf("Move list pointer to %u\n", pointer);
|
|
} else if (et == kp_SHORT_CLICK) {
|
|
if (ev == kp_KEYENCODER) {
|
|
discare_kp_events();
|
|
printf("Confirm list item %u\n", pointer);
|
|
IndexResult ret = {pointer, 1};
|
|
return ret;
|
|
}
|
|
} else if (et == kp_LONG_PRESS) {
|
|
if (ev == kp_KEYENCODER) {
|
|
discare_kp_events();
|
|
printf("Cancel list item %u\n", pointer);
|
|
IndexResult ret = {pointer, 0};
|
|
return ret;
|
|
}
|
|
} else if (et != kp_NOP) {
|
|
printf("Unhandled event: %u %u\n", et, ev);
|
|
}
|
|
// render items
|
|
if (tmp_pointer == U8_RESET) {
|
|
// need render
|
|
if (last_pointer == U8_RESET) {
|
|
// render all
|
|
render_page_number((pointer / LIST_PAGE_SIZE) + 1, (item_count + LIST_PAGE_SIZE - 1) / LIST_PAGE_SIZE);
|
|
for (tmp_pointer = 0; tmp_pointer < LIST_PAGE_SIZE; tmp_pointer ++) {
|
|
uint16_t current = page_start + tmp_pointer;
|
|
if (current >= item_count) {
|
|
uiu_text_area(font_unifont_8x16, u8str(" "), 1,
|
|
UI_LIST_OFFSET_X(tmp_pointer), UI_LIST_OFFSET_Y(tmp_pointer),
|
|
UI_LIST_WIDTH(tmp_pointer), font_unifont_8x16->char_height,
|
|
uiu_ALIGN_HCENTER | uiu_ALIGN_VCENTER, ST7735_WHITE, ST7735_BLACK
|
|
);
|
|
continue;
|
|
}
|
|
StrItem item = get_item(current);
|
|
if (current == pointer) {
|
|
uiu_text_area(font_unifont_8x16, item.text, item.len,
|
|
UI_LIST_OFFSET_X(tmp_pointer), UI_LIST_OFFSET_Y(tmp_pointer),
|
|
UI_LIST_WIDTH(tmp_pointer), font_unifont_8x16->char_height,
|
|
uiu_ALIGN_HCENTER | uiu_ALIGN_VCENTER, ST7735_GREEN, LIST_STYLE_SELECTED_COLOR_BG
|
|
);
|
|
last_pointer = tmp_pointer;
|
|
} else {
|
|
uiu_text_area(font_unifont_8x16, item.text, item.len,
|
|
UI_LIST_OFFSET_X(tmp_pointer), UI_LIST_OFFSET_Y(tmp_pointer),
|
|
UI_LIST_WIDTH(tmp_pointer), font_unifont_8x16->char_height,
|
|
uiu_ALIGN_HCENTER | uiu_ALIGN_VCENTER, ST7735_WHITE, ST7735_BLACK
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
StrItem item = get_item(page_start + last_pointer);
|
|
uiu_text_area(font_unifont_8x16, item.text, item.len,
|
|
UI_LIST_OFFSET_X(last_pointer), UI_LIST_OFFSET_Y(last_pointer),
|
|
UI_LIST_WIDTH(last_pointer), font_unifont_8x16->char_height,
|
|
uiu_ALIGN_HCENTER | uiu_ALIGN_VCENTER, ST7735_WHITE, ST7735_BLACK
|
|
);
|
|
last_pointer = pointer - page_start;
|
|
StrItem item_curr = get_item(pointer);
|
|
uiu_text_area(font_unifont_8x16, item_curr.text, item_curr.len,
|
|
UI_LIST_OFFSET_X(last_pointer), UI_LIST_OFFSET_Y(last_pointer),
|
|
UI_LIST_WIDTH(last_pointer), font_unifont_8x16->char_height,
|
|
uiu_ALIGN_HCENTER | uiu_ALIGN_VCENTER, ST7735_GREEN, LIST_STYLE_SELECTED_COLOR_BG
|
|
);
|
|
}
|
|
tmp_pointer = 0;
|
|
}
|
|
}
|
|
}
|