Add browser option

pull/52/head
DiSlord Live 3 years ago
parent be63b81b1b
commit 01e87fc27b

@ -92,6 +92,7 @@
#define __USE_SD_CARD__ // Enable SD card support
#define __SD_CARD_LOAD__ // Allow run commands from SD card (config.ini in root)
#define __SD_CARD_DUMP_FIRMWARE__ // Allow dump firmware to SD card
#define __SD_FILE_BROWSER__
#define __LCD_BRIGHTNESS__ // LCD or hardware allow change brightness, add menu item for this
#define __HARMONIC__
#define __NOISE_FIGURE__
@ -584,6 +585,14 @@ extern uint16_t graph_bottom;
#define MENU_BUTTON_HEIGHT_N(n) (LCD_HEIGHT/(n)-1)
#define BROWSER_BUTTON_BORDER 1
// Browser window settings
#define FILES_COLUMNS (LCD_WIDTH/160) // columns in browser
#define FILES_ROWS 10 // rows in browser
#define FILES_PER_PAGE (FILES_COLUMNS*FILES_ROWS) // FILES_ROWS * FILES_COLUMNS
#define FILE_BOTTOM_HEIGHT 20 // Height of bottom buttons (< > X)
#define FILE_BUTTON_HEIGHT ((LCD_HEIGHT - FILE_BOTTOM_HEIGHT)/FILES_ROWS) // Height of file buttons
// Define message box width
#ifdef TINYSA4
#define MESSAGE_BOX_WIDTH 300
@ -1448,7 +1457,7 @@ int invoke_quick_menu(int);
bool ui_process_listen_lever(void);
void refresh_sweep_menu(int i);
void save_to_sd(int mask);
void drawMessageBox(char *header, char *text, uint32_t delay);
void drawMessageBox(const char *header, char *text, uint32_t delay);
// Irq operation process set
#define OP_NONE 0x00

139
ui.c

@ -74,7 +74,11 @@ volatile uint8_t operation_requested = OP_NONE;
int8_t previous_marker = MARKER_INVALID;
enum {
UI_NORMAL, UI_MENU, UI_KEYPAD
UI_NORMAL, UI_MENU, UI_KEYPAD,
#ifdef __SD_FILE_BROWSER__
UI_BROWSER,
#endif
UI_END
};
#define NUMINPUT_LEN 12
@ -111,7 +115,8 @@ static const uint8_t slider_bitmap[]=
#define AUTO_ICON(S) (S>=2?BUTTON_ICON_CHECK_AUTO:S) // Depends on order of ICONs!!!!!
#define BUTTON_BORDER_NONE 0x00
#define BUTTON_BORDER_WIDTH_MASK 0x0F
#define BUTTON_BORDER_WIDTH_MASK 0x07
#define BUTTON_BORDER_NO_FILL 0x08
// Define mask for draw border (if 1 use light color, if 0 dark)
#define BUTTON_BORDER_TYPE_MASK 0xF0
@ -147,6 +152,7 @@ static void erase_menu_buttons(void);
static void ui_process_keypad(void);
static void choose_active_marker(void);
static void menu_move_back(bool leave_ui);
static void draw_button(uint16_t x, uint16_t y, uint16_t w, uint16_t h, ui_button_t *b);
//static const menuitem_t menu_marker_type[];
static int btn_check(void)
@ -3503,6 +3509,60 @@ static UI_FUNCTION_ADV_CALLBACK(menu_connection_acb)
#endif
#ifdef __USE_SD_CARD__
//*******************************************************************************************
// Bitmap file header for LCD_WIDTH x LCD_HEIGHT image 16bpp (v4 format allow set RGB mask)
//*******************************************************************************************
#define BMP_UINT32(val) ((val)>>0)&0xFF, ((val)>>8)&0xFF, ((val)>>16)&0xFF, ((val)>>24)&0xFF
#define BMP_UINT16(val) ((val)>>0)&0xFF, ((val)>>8)&0xFF
#define BMP_H1_SIZE (14) // BMP header 14 bytes
#define BMP_V4_SIZE (108) // v4 header 108 bytes
#define BMP_HEAD_SIZE (BMP_H1_SIZE + BMP_V4_SIZE) // Size of all headers
#define BMP_SIZE (2*LCD_WIDTH*LCD_HEIGHT) // Bitmap size = 2*w*h
#define BMP_FILE_SIZE (BMP_SIZE + BMP_HEAD_SIZE) // File size = headers + bitmap
static const uint8_t bmp_header_v4[BMP_H1_SIZE + BMP_V4_SIZE] = {
// BITMAPFILEHEADER (14 byte size)
0x42, 0x4D, // BM signature
BMP_UINT32(BMP_FILE_SIZE), // File size (h + v4 + bitmap)
BMP_UINT16(0), // reserved
BMP_UINT16(0), // reserved
BMP_UINT32(BMP_HEAD_SIZE), // Size of all headers (h + v4)
// BITMAPINFOv4 (108 byte size)
BMP_UINT32(BMP_V4_SIZE), // Data offset after this point (v4 size)
BMP_UINT32(LCD_WIDTH), // Width
BMP_UINT32(LCD_HEIGHT), // Height
BMP_UINT16(1), // Planes
BMP_UINT16(16), // 16bpp
BMP_UINT32(3), // Compression (BI_BITFIELDS)
BMP_UINT32(BMP_SIZE), // Bitmap size (w*h*2)
BMP_UINT32(0x0EC4), // x Resolution (96 DPI = 96 * 39.3701 inches per meter = 0x0EC4)
BMP_UINT32(0x0EC4), // y Resolution (96 DPI = 96 * 39.3701 inches per meter = 0x0EC4)
BMP_UINT32(0), // Palette size
BMP_UINT32(0), // Palette used
// Extend v4 header data (color mask for RGB565)
BMP_UINT32(0b1111100000000000),// R mask = 0b11111000 00000000
BMP_UINT32(0b0000011111100000),// G mask = 0b00000111 11100000
BMP_UINT32(0b0000000000011111),// B mask = 0b00000000 00011111
BMP_UINT32(0b0000000000000000),// A mask = 0b00000000 00000000
'B','G','R','s', // CSType = 'sRGB'
BMP_UINT32(0), // ciexyzRed.ciexyzX Endpoints
BMP_UINT32(0), // ciexyzRed.ciexyzY
BMP_UINT32(0), // ciexyzRed.ciexyzZ
BMP_UINT32(0), // ciexyzGreen.ciexyzX
BMP_UINT32(0), // ciexyzGreen.ciexyzY
BMP_UINT32(0), // ciexyzGreen.ciexyzZ
BMP_UINT32(0), // ciexyzBlue.ciexyzX
BMP_UINT32(0), // ciexyzBlue.ciexyzY
BMP_UINT32(0), // ciexyzBlue.ciexyzZ
BMP_UINT32(0), // GammaRed
BMP_UINT32(0), // GammaGreen
BMP_UINT32(0), // GammaBlue
};
static void swap_bytes(uint16_t *buf, int size) {
for (int i = 0; i < size; i++)
buf[i] = __REVSH(buf[i]); // swap byte order (example 0x10FF to 0xFF10)
}
static uint16_t file_mask;
// Save format enum
@ -3534,6 +3594,10 @@ static UI_FUNCTION_CALLBACK(menu_sdcard_cb) {
(void)item;
sa_save_file(0, data);
}
#ifdef __SD_FILE_BROWSER__
#include "vna_browser.c"
#endif
#endif
// ===[MENU DEFINITION]=========================================================
// Back button submenu list
@ -4025,6 +4089,9 @@ static const menuitem_t menu_settings[] =
#ifdef __SD_CARD_DUMP_FIRMWARE__
{ MT_CALLBACK, FMT_BIN_FILE, "DUMP\nFIRMWARE", menu_sdcard_cb},
#endif
#ifdef __SD_FILE_BROWSER__
{ MT_CALLBACK, FMT_BMP_FILE, "LOAD BMP", menu_sdcard_browse_cb },
#endif
#ifdef TINYSA4
{ MT_ADV_CALLBACK, 0, "INTERNALS", menu_internals_acb},
#endif
@ -5469,7 +5536,7 @@ draw_button(uint16_t x, uint16_t y, uint16_t w, uint16_t h, ui_button_t *b)
{
uint16_t bw = b->border&BUTTON_BORDER_WIDTH_MASK;
ili9341_set_foreground(b->fg);
ili9341_set_background(b->bg);ili9341_fill(x + bw, y + bw, w - (bw * 2), h - (bw * 2));
ili9341_set_background(b->bg);
if (bw==0) return;
uint16_t br = LCD_RISE_EDGE_COLOR;
uint16_t bd = LCD_FALLEN_EDGE_COLOR;
@ -5480,9 +5547,11 @@ draw_button(uint16_t x, uint16_t y, uint16_t w, uint16_t h, ui_button_t *b)
ili9341_set_background(type&BUTTON_BORDER_BOTTOM ? br : bd);ili9341_fill(x, y + h - bw, w, bw); // bottom
// Set colors for button text after
ili9341_set_background(b->bg);
if (type & BUTTON_BORDER_NO_FILL) return;
ili9341_fill(x + bw, y + bw, w - (bw * 2), h - (bw * 2));
}
void drawMessageBox(char *header, char *text, uint32_t delay){
void drawMessageBox(const char *header, char *text, uint32_t delay){
ui_button_t b;
b.bg = LCD_MENU_COLOR;
b.fg = LCD_MENU_TEXT_COLOR;
@ -6478,6 +6547,9 @@ ui_process_lever(void)
// case UI_KEYPAD:
// ui_process_keypad();
// break;
case UI_BROWSER:
ui_process_browser_lever();
break;
}
}
@ -6555,60 +6627,6 @@ static int touch_quick_menu(int touch_x, int touch_y)
}
#ifdef __USE_SD_CARD__
//*******************************************************************************************
// Bitmap file header for LCD_WIDTH x LCD_HEIGHT image 16bpp (v4 format allow set RGB mask)
//*******************************************************************************************
#define BMP_UINT32(val) ((val)>>0)&0xFF, ((val)>>8)&0xFF, ((val)>>16)&0xFF, ((val)>>24)&0xFF
#define BMP_UINT16(val) ((val)>>0)&0xFF, ((val)>>8)&0xFF
#define BMP_H1_SIZE (14) // BMP header 14 bytes
#define BMP_V4_SIZE (108) // v4 header 108 bytes
#define BMP_HEAD_SIZE (BMP_H1_SIZE + BMP_V4_SIZE) // Size of all headers
#define BMP_SIZE (2*LCD_WIDTH*LCD_HEIGHT) // Bitmap size = 2*w*h
#define BMP_FILE_SIZE (BMP_SIZE + BMP_HEAD_SIZE) // File size = headers + bitmap
static const uint8_t bmp_header_v4[BMP_H1_SIZE + BMP_V4_SIZE] = {
// BITMAPFILEHEADER (14 byte size)
0x42, 0x4D, // BM signature
BMP_UINT32(BMP_FILE_SIZE), // File size (h + v4 + bitmap)
BMP_UINT16(0), // reserved
BMP_UINT16(0), // reserved
BMP_UINT32(BMP_HEAD_SIZE), // Size of all headers (h + v4)
// BITMAPINFOv4 (108 byte size)
BMP_UINT32(BMP_V4_SIZE), // Data offset after this point (v4 size)
BMP_UINT32(LCD_WIDTH), // Width
BMP_UINT32(LCD_HEIGHT), // Height
BMP_UINT16(1), // Planes
BMP_UINT16(16), // 16bpp
BMP_UINT32(3), // Compression (BI_BITFIELDS)
BMP_UINT32(BMP_SIZE), // Bitmap size (w*h*2)
BMP_UINT32(0x0EC4), // x Resolution (96 DPI = 96 * 39.3701 inches per meter = 0x0EC4)
BMP_UINT32(0x0EC4), // y Resolution (96 DPI = 96 * 39.3701 inches per meter = 0x0EC4)
BMP_UINT32(0), // Palette size
BMP_UINT32(0), // Palette used
// Extend v4 header data (color mask for RGB565)
BMP_UINT32(0b1111100000000000),// R mask = 0b11111000 00000000
BMP_UINT32(0b0000011111100000),// G mask = 0b00000111 11100000
BMP_UINT32(0b0000000000011111),// B mask = 0b00000000 00011111
BMP_UINT32(0b0000000000000000),// A mask = 0b00000000 00000000
'B','G','R','s', // CSType = 'sRGB'
BMP_UINT32(0), // ciexyzRed.ciexyzX Endpoints
BMP_UINT32(0), // ciexyzRed.ciexyzY
BMP_UINT32(0), // ciexyzRed.ciexyzZ
BMP_UINT32(0), // ciexyzGreen.ciexyzX
BMP_UINT32(0), // ciexyzGreen.ciexyzY
BMP_UINT32(0), // ciexyzGreen.ciexyzZ
BMP_UINT32(0), // ciexyzBlue.ciexyzX
BMP_UINT32(0), // ciexyzBlue.ciexyzY
BMP_UINT32(0), // ciexyzBlue.ciexyzZ
BMP_UINT32(0), // GammaRed
BMP_UINT32(0), // GammaGreen
BMP_UINT32(0), // GammaBlue
};
static void swap_bytes(uint16_t *buf, int size) {
for (int i = 0; i < size; i++)
buf[i] = __REVSH(buf[i]); // swap byte order (example 0x10FF to 0xFF10)
}
// Create file name from current time
static FRESULT sa_create_file(char *fs_filename)
{
@ -6848,6 +6866,9 @@ void ui_process_touch(void)
case UI_MENU:
menu_apply_touch(touch_x, touch_y);
break;
case UI_BROWSER:
browser_apply_touch(touch_x, touch_y);
break;
}
}
}
@ -6868,7 +6889,7 @@ ui_process(void)
operation_requested = OP_NONE;
}
if (operation_requested&OP_TOUCH) {
ui_process_touch();
ui_process_touch();
operation_requested = OP_NONE;
}
touch_start_watchdog();

@ -0,0 +1,346 @@
static uint16_t file_count;
static uint16_t page_count;
static uint16_t current_page;
static uint16_t sel_mode;
// Buttons in browser
enum {FILE_BUTTON_LEFT = 0, FILE_BUTTON_RIGHT, FILE_BUTTON_EXIT, FILE_BUTTON_DEL, FILE_BUTTON_FILE};
// Button position on screen
typedef struct {
uint16_t x;
uint16_t y;
uint16_t w;
uint8_t h;
uint8_t ofs;
} browser_btn_t;
static const browser_btn_t browser_btn[] = {
[FILE_BUTTON_LEFT] = { 0 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // < previous
[FILE_BUTTON_RIGHT]= {LCD_WIDTH/2 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // > next
[FILE_BUTTON_EXIT] = {LCD_WIDTH - 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, 40, FILE_BOTTOM_HEIGHT, ( 40 - FONT_WIDTH)/2}, // X exit
[FILE_BUTTON_DEL] = { 0 + 0, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, 40, FILE_BOTTOM_HEIGHT, ( 40 - 3*FONT_WIDTH)/2}, // DEL
// File button, only size and start position, must be idx = FILE_BUTTON_FILE
[FILE_BUTTON_FILE] = { 0, 0, LCD_WIDTH/FILES_COLUMNS, FILE_BUTTON_HEIGHT, 5},
};
static void browser_get_button_pos(int idx, browser_btn_t *b) {
int n = idx >= FILE_BUTTON_FILE ? FILE_BUTTON_FILE : idx;
#if 0
memcpy(b, &browser_btn[n], sizeof(browser_btn_t));
#else
b->x = browser_btn[n].x;
b->y = browser_btn[n].y;
b->w = browser_btn[n].w;
b->h = browser_btn[n].h;
b->ofs = browser_btn[n].ofs;
#endif
if (idx > FILE_BUTTON_FILE) { // for file buttons use multiplier from start offset
idx-= FILE_BUTTON_FILE;
b->x+= b->w * (idx / FILES_ROWS);
b->y+= b->h * (idx % FILES_ROWS);
}
}
static void browser_draw_button(int idx, const char *txt) {
if (idx < 0) return;
ui_button_t b;
browser_btn_t btn;
browser_get_button_pos(idx, &btn);
// Mark DEL button in file delete mode
b.bg = (idx == FILE_BUTTON_DEL && sel_mode) ? LCD_LOW_BAT_COLOR : LCD_MENU_COLOR;
b.fg = LCD_MENU_TEXT_COLOR;
b.border = (idx == selection) ? BROWSER_BUTTON_BORDER|BUTTON_BORDER_FALLING : BROWSER_BUTTON_BORDER|BUTTON_BORDER_RISE;
if (txt == NULL) b.border|= BUTTON_BORDER_NO_FILL;
draw_button(btn.x, btn.y, btn.w, btn.h, &b);
if (txt) lcd_printf(btn.x + btn.ofs, btn.y + (btn.h - FONT_STR_HEIGHT) / 2, txt);
}
static char to_lower(char c) {return (c >='A' && c <= 'Z') ? c - 'A' + 'a' : c;}
static bool strcmpi(const char *t1, const char *t2) {
int i = 0;
while (1) {
char ch1 = to_lower(t1[i]), ch2 = to_lower(t2[i]);
if (ch1 != ch2) return false;
if (ch1 == 0) return true;
i++;
}
}
static bool compare_ext(const char *name, const char *ext) {
int i = 0, j = 0;
while (name[i]) if (name[i++] == '.') j = i; // Get last '.' position + 1
return j == 0 ? false : strcmpi(&name[j], ext); // Compare text after '.' and ext
}
static FRESULT sd_findnext(DIR* dp, FILINFO* fno) {
while (f_readdir(dp, fno) == FR_OK && fno->fname[0]) {
if (fno->fattrib & AM_DIR) continue;
if (compare_ext(fno->fname, dp->pat)) return FR_OK;
//#if FF_USE_LFN && FF_USE_FIND == 2
// if (compare_ext(fno->altname, dp->pat)) return FR_OK;
//#endif
}
return FR_NO_FILE;
}
static FRESULT sd_open_dir(DIR* dp, const TCHAR* path, const TCHAR* pattern) {
dp->pat = pattern;
return f_opendir(dp, path);
}
static void browser_open_file(int sel) {
FILINFO fno;
FRESULT res;
DIR dj;
int cnt;
if ((uint16_t)sel >= file_count) return;
if (f_mount(fs_volume, "", 1) != FR_OK) return;
repeat:
cnt = sel;
if (sd_open_dir(&dj, "", file_ext[keypad_mode]) != FR_OK) return; // open dir
while (sd_findnext(&dj, &fno) == FR_OK && cnt != 0) cnt--; // skip cnt files
f_closedir(&dj);
if (cnt != 0) return;
// Delete file if in delete mode
if (sel_mode) {f_unlink(fno.fname); return;}
const char *error = NULL;
bool leave_show = true;
UINT size;
if (f_open(fs_file, fno.fname, FA_READ) != FR_OK) return;
ili9341_set_foreground(LCD_FG_COLOR);
ili9341_set_background(LCD_BG_COLOR);
switch (keypad_mode) {
//#ifdef __SD_CARD_LOAD__
// case FMT_CMD_FILE:
// {
// const int buffer_size = 256;
// const int line_size = 128;
// char *buf_8 = (char *)spi_buffer; // must be greater then buffer_size + line_size
// char *line = buf_8 + buffer_size;
// uint16_t j = 0, i;
// while (f_read(fs_file, buf_8, buffer_size, &size) == FR_OK && size > 0) {
// for (i = 0; i < size; i++) {
// uint8_t c = buf_8[i];
// if (c == '\r') { // New line (Enter)
// line[j] = 0; j = 0;
// VNAShell_executeCMDLine(line);
// }
// else if (c < 0x20) continue; // Others (skip)
// else if (j < line_size) line[j++] = (char)c; // Store
// }
// }
// break;
// }
//#endif
/*
* BMP file load procedure, load only device screenshots
*/
case FMT_BMP_FILE:
{
int y;
leave_show = false; // allow step up/down load bitmap
uint16_t *buf_16 = spi_buffer; // prepare buffer
res = f_read(fs_file, (void *)buf_16, sizeof(bmp_header_v4), &size); // read heaser
if (res != FR_OK || buf_16[9] != LCD_WIDTH || buf_16[11] != LCD_HEIGHT || buf_16[14] != 16) {error = "Format err"; break;}
for (y = LCD_HEIGHT-1; y >=0 && res == FR_OK; y--) {
res = f_read(fs_file, (void *)buf_16, LCD_WIDTH * sizeof(uint16_t), &size);
swap_bytes(buf_16, LCD_WIDTH);
ili9341_bulk(0, y, LCD_WIDTH, 1);
}
lcd_printf(0, LCD_HEIGHT - 3*FONT_STR_HEIGHT, fno.fname);
}
break;
/*
* Load calibration
*/
// case FMT_CAL_FILE:
// {
// uint32_t magic;
// char *src = (char*)&current_props + sizeof(magic);
// uint32_t total = sizeof(current_props) - sizeof(magic);
// // Compare file size and try read magic header, if all OK load it
// if (fno.fsize == sizeof(current_props) && f_read(fs_file, &magic, sizeof(magic), &size) == FR_OK &&
// magic == PROPS_MAGIC && f_read(fs_file, src, total, &size) == FR_OK)
// load_properties(NO_SAVE_SLOT);
// else error = "Format err";
// }
// break;
default: break;
}
f_close(fs_file);
if (error) {
ili9341_clear_screen();
drawMessageBox(error, fno.fname, leave_show ? 2000 : 0);
}
if (leave_show) return;
// Process input
while (1) {
uint16_t status = btn_check();
int key = -1;
if (status & EVT_DOWN) key = 0;
if (status & EVT_UP ) key = 1;
if (status & EVT_BUTTON_SINGLE_CLICK) key = 2;
status = touch_check();
if (status == EVT_TOUCH_PRESSED || status == EVT_TOUCH_DOWN) {
int touch_x, touch_y;
touch_position(&touch_x, &touch_y);
if (touch_x < LCD_WIDTH *1/3) key = 0;
else if (touch_x < LCD_WIDTH *2/3) key = 2;
else key = 1;
touch_wait_release();
}
chThdSleepMilliseconds(100);
int old_sel = sel;
if (key == 0) {if (--sel < 0) sel = file_count - 1;}
else if (key == 1) {if (++sel > file_count - 1) sel = 0;}
else if (key == 2) break;
if (old_sel != sel) goto repeat;
}
}
static void browser_draw_buttons(void) {
browser_draw_button(FILE_BUTTON_DEL, "DEL");
browser_draw_button(FILE_BUTTON_LEFT, "<");
browser_draw_button(FILE_BUTTON_RIGHT, ">");
browser_draw_button(FILE_BUTTON_EXIT, "X");
}
static void browser_draw_page(int page) {
FILINFO fno;
DIR dj;
// Mount SD card and open directory
if (f_mount(fs_volume, "", 1) != FR_OK ||
sd_open_dir(&dj, "", file_ext[keypad_mode]) != FR_OK) {
drawMessageBox("ERROR", "NO CARD", 2000);
ui_mode_normal();
return;
}
// Draw Browser UI
int cnt = 0;
uint16_t start_file = (page - 1) * FILES_PER_PAGE;
ili9341_set_background(LCD_MENU_COLOR);
ili9341_clear_screen();
while (sd_findnext(&dj, &fno) == FR_OK) {
if (cnt >= start_file && cnt < (start_file + FILES_PER_PAGE)) {
//uint16_t sec = ((fno.ftime<<1) & 0x3F);
//uint16_t min = ((fno.ftime>>5) & 0x3F);
//uint16_t h = ((fno.ftime>>11) & 0x1F);
//uint16_t d = ((fno.fdate>>0) & 0x1F);
//uint16_t m = ((fno.fdate>>5) & 0x0F);
//uint16_t year= ((fno.fdate>>9) & 0x3F) + 1980;
//lcd_printf(x, y, "%2d %s %u - %u/%02u/%02u %02u:%02u:%02u", cnt, fno.fname, fno.fsize, year, m, d, h, min, sec);
browser_draw_button(cnt - start_file + FILE_BUTTON_FILE, fno.fname);
}
cnt++;
if (file_count && (start_file + FILES_PER_PAGE == cnt)) break;
}
f_closedir(&dj);
// Calculate page and file count on first run
if (file_count == 0) {
file_count = cnt;
page_count = cnt == 0 ? 1 : (file_count + FILES_PER_PAGE - 1) / FILES_PER_PAGE;
}
browser_draw_buttons();
lcd_printf(LCD_WIDTH / 2 - 3 * FONT_WIDTH, LCD_HEIGHT - (FILE_BOTTOM_HEIGHT + FONT_STR_HEIGHT) / 2, "- %u | %u -", page, page_count);
return;
}
static void browser_key_press(int key) {
int page;
switch (key) {
case FILE_BUTTON_LEFT:
case FILE_BUTTON_RIGHT: // Switch page on left / right change
page = current_page;
if (key == FILE_BUTTON_LEFT && --current_page < 1) current_page = page_count;
if (key == FILE_BUTTON_RIGHT && ++current_page > page_count) current_page = 1;
if (page != current_page)
browser_draw_page(current_page);
break;
case FILE_BUTTON_EXIT: //Exit
ui_mode_normal();
break;
case FILE_BUTTON_DEL: // Toggle delete mode
sel_mode^= 1;
browser_draw_buttons();
break;
case FILE_BUTTON_FILE: // Open or delete file
default:
browser_open_file(key - FILE_BUTTON_FILE + (current_page - 1) * FILES_PER_PAGE);
if (sel_mode) {
file_count = 0; // Reeset file count (recalculate on draw page)
selection = -1; // Reset delection
sel_mode = 0; // Exit file delete mode
browser_draw_page(current_page);
return;
}
ui_mode_normal(); // Exit
break;
}
}
static int browser_get_max(void) {
// get max buttons depend from page and file count
int max = current_page == page_count ? (file_count % FILES_PER_PAGE) : FILES_PER_PAGE;
if (file_count > 0 && max == 0) max = FILES_PER_PAGE;
return max + FILE_BUTTON_FILE - 1;
}
// Process UI input for browser
static void browser_apply_touch(int touch_x, int touch_y) {
browser_btn_t btn;
int old = selection;
int max = browser_get_max();
for (int idx = 0; idx <= max; idx++) {
browser_get_button_pos(idx, &btn);
if (touch_x < btn.x || touch_x >= btn.x + btn.w ||
touch_y < btn.y || touch_y >= btn.y + btn.h) continue;
// Found button under touch
browser_draw_button(selection = idx, NULL); // draw new selection
browser_draw_button(old, NULL); // clear old
touch_wait_release();
selection = -1;
browser_draw_button(idx, NULL); // clear selection
browser_key_press(idx);
return;
}
}
static void ui_process_browser_lever(void) {
uint16_t status = btn_check();
if (status == 0) return;
if (status == EVT_BUTTON_SINGLE_CLICK) {
if (selection >= 0) browser_key_press(selection); // Process click
return;
}
int max = browser_get_max();
do {
int old = selection;
if((status & EVT_DOWN) && --selection < 0) selection = max;
if((status & EVT_UP) && ++selection > max) selection = 0;
if (old != selection) {
browser_draw_button(old, NULL); // clear old selection
browser_draw_button(selection, NULL); // draw new selection
}
chThdSleepMilliseconds(100);
} while ((status = btn_wait_release()) != 0);
}
static UI_FUNCTION_CALLBACK(menu_sdcard_browse_cb) {
(void)item;
if (ui_mode == UI_BROWSER)
return;
area_width = 0;
area_height = 0;
ui_mode = UI_BROWSER;
keypad_mode = data;
current_page = 1;
file_count = 0;
selection = -1;
sel_mode = 0;
browser_draw_page(current_page);
}
Loading…
Cancel
Save

Powered by TurnKey Linux.