2023-02-03 01:22:15 +08:00

235 lines
9.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdint.h>
#include "global.h"
#include "ui.h"
#include "time.h"
#include "st7735.h"
#include "Images/digi18x32.h"
#include "Images/img_stereo.h"
#include "monoimg.h"
#include "bmfont.h"
#include "asciifont.h"
void ui_text_number18x32(uint32_t num, uint16_t x, uint16_t y, uint16_t color) {
uint32_t tmp = num;
uint32_t div = 1;
uint8_t num_count = 0;
while (tmp > 0) {
tmp = tmp / 10;
num_count ++;
div = div * 10;
}
div = div / 10;
if (div == 0) {
mimg_Area area = mimg_get_tile_area(IMG_DIGI_18_32, 10, 1, 0);
mimg_draw(ST7735_DrawPixel, x, y, color, IMG_DIGI_18_32, area);
} else {
while (div > 0) {
tmp = (num / div) % 10;
mimg_Area area = mimg_get_tile_area(IMG_DIGI_18_32, 10, 1, tmp);
mimg_draw(ST7735_DrawPixel, x, y, color, IMG_DIGI_18_32, area);
x = x + 18;
div = div / 10;
}
}
}
void ui_text_number18x32_with_bg(uint32_t num, uint16_t x, uint16_t y, uint16_t color, uint16_t bg_color) {
uint32_t tmp = num;
uint32_t div = 1;
uint8_t num_count = 0;
while (tmp > 0) {
tmp = tmp / 10;
num_count ++;
div = div * 10;
}
div = div / 10;
if (div == 0) {
mimg_Area area = mimg_get_tile_area(IMG_DIGI_18_32, 10, 1, 0);
mimg_draw_with_bg(ST7735_DrawPixel, x, y, color, bg_color, IMG_DIGI_18_32, area);
} else {
while (div > 0) {
tmp = (num / div) % 10;
mimg_Area area = mimg_get_tile_area(IMG_DIGI_18_32, 10, 1, tmp);
mimg_draw_with_bg(ST7735_DrawPixel, x, y, color, bg_color, IMG_DIGI_18_32, area);
x = x + 18;
div = div / 10;
}
}
}
// TODO: 绘制界面的函数
/* UI元素 */
void ui_com_main_border() {
// border
ST7735_FillRectangle(0, 0, ST7735_WIDTH, 1, ST7735_YELLOW);
ST7735_FillRectangle(0, 17, ST7735_WIDTH, 1, ST7735_YELLOW);
ST7735_FillRectangle(0, ST7735_HEIGHT - 34, ST7735_WIDTH, 1, ST7735_YELLOW);
ST7735_FillRectangle(0, ST7735_HEIGHT - 1, ST7735_WIDTH, 1, ST7735_YELLOW);
ST7735_FillRectangle(0, 0, 1, ST7735_HEIGHT, ST7735_YELLOW);
ST7735_FillRectangle(ST7735_WIDTH - 1, 0, 1, ST7735_HEIGHT, ST7735_YELLOW);
}
void ui_com_title_bar(uint8_t clear, uint8_t *text, uint32_t bytes_len) {
if (clear) {
ST7735_FillRectangle(1, 1, ST7735_WIDTH - 2, 16, ST7735_BLACK);
}
uint16_t off_x = (ST7735_WIDTH - 2 - bmf_get_text_width(font_unifont_8x16, text, bytes_len)) / 2 + 1;
bmf_draw_text(font_unifont_8x16, text, bytes_len, off_x, 1, ST7735_WIDTH - 2, 16, ST7735_YELLOW);
}
void ui_com_freq_digital(uint8_t clear, uint8_t only_pointer) {
// 5位数字, 即高32+2(小数点高度)宽90
uint16_t off_x = (ST7735_WIDTH - 90) / 2;
uint16_t off_y = (ST7735_HEIGHT - 34 - 34 - 18) / 2 + 17;
uint16_t freq_num;
if (global_data.rf_mode == G_RF_MODE_AM) {
freq_num = global_data.freq;
} else {
freq_num = global_data.freq * 5;
}
uint16_t color_orange = ST7735_COLOR565(0xFF, 0x7F, 0);
if (clear) {
if (global_data.rf_mode == G_RF_MODE_AM) {
ST7735_FillRectangle(off_x, off_y+32, 90, 3, ST7735_BLACK); // 清除小数点
} else {
ST7735_FillRectangle(off_x, off_y + 32, 18 * 3 - 1, 3, ST7735_BLACK); // 清除小数点
ST7735_FillRectangle(off_x + (18 * 3) + 1, off_y + 32, 18 * 2 - 1, 3, ST7735_BLACK); // 清除小数点
ST7735_FillRectangle(off_x + (18 * 3) - 1, off_y + 34, 2, 1, ST7735_BLACK);
}
}
if (global_data.rf_mode == G_RF_MODE_FM) {
// 绘制小数点
ST7735_FillRectangle(off_x + (18 * 3) - 1, off_y + 32, 2, 2, color_orange);
}
if (global_data.point_mode & G_PMOD_MODE_MASK) {
// 绘制光标
uint8_t blink_state = (ticks_ms() / UI_BLINK_MS) % 2;
uint8_t blink_state2 = !(global_data.point_mode & G_PMOD_PBLINK_MASK);
if (!(global_data.point_mode & G_PMOD_PMOVE_MASK) || (blink_state ^ blink_state2)) {
uint8_t p_pos = bit_fetch(global_data.point_mode, G_POMD_POS_BOFF, G_POMD_POS_MASK);
uint16_t p_off = (4 - p_pos) * 18 + 2 + off_x;
ST7735_FillRectangle(p_off, off_y + 33, 14, 2, color_orange);
bit_set(global_data.point_mode, G_PMOD_PBLINK2_MASK);
} else {
bit_clear(global_data.point_mode, G_PMOD_PBLINK2_MASK);
}
}
uint16_t scale = 10000;
uint32_t tmp = 0;
if (!only_pointer) {
while (scale > 0) {
tmp = (freq_num / scale) % 10;
if (clear) {
ui_text_number18x32_with_bg(tmp, off_x, off_y, color_orange, ST7735_BLACK);
} else {
ui_text_number18x32(tmp, off_x, off_y, color_orange);
}
off_x += 18;
scale /= 10;
}
}
}
void ui_com_fm_am(uint8_t clear) {
uint16_t area_w = (ST7735_WIDTH - 90) / 2 - 1;
uint16_t off_x = 1;
uint16_t off_y = 34 + 32;
if (clear) {
ST7735_FillRectangle(off_x, off_y, area_w, 16, ST7735_BLACK);
ST7735_FillRectangle(ST7735_WIDTH - area_w - 1 - 1, off_y, area_w, 16, ST7735_BLACK);
}
if (global_data.rf_mode == G_RF_MODE_AM) {
off_x = (area_w - bmf_get_text_width(font_unifont_8x16, u8str("AM"), 2)) / 2;
bmf_draw_text(font_unifont_8x16, u8str("AM"), 2, off_x, off_y, area_w, 16, ST7735_YELLOW);
off_x = ST7735_WIDTH - area_w - 1 + (area_w - bmf_get_text_width(font_unifont_8x16, u8str("KHz"), 3)) / 2;
bmf_draw_text(font_unifont_8x16, u8str("KHz"), 3, off_x, off_y, area_w, 16, ST7735_BLUE);
} else {
off_x = (area_w - bmf_get_text_width(font_unifont_8x16, u8str("FM"), 2)) / 2;
bmf_draw_text(font_unifont_8x16, u8str("FM"), 2, off_x, off_y, area_w, 16, ST7735_GREEN);
off_x = ST7735_WIDTH - area_w - 1 + (area_w - bmf_get_text_width(font_unifont_8x16, u8str("MHz"), 3)) / 2;
bmf_draw_text(font_unifont_8x16, u8str("MHz"), 3, off_x, off_y, area_w, 16, ST7735_BLUE);
}
}
void ui_com_progress_bar(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t border_color, uint16_t fill_color, uint32_t current, uint32_t total) {
// border
ST7735_FillRectangle(x, y, w, 1, border_color);
ST7735_FillRectangle(x, y + h - 1, w, 1, border_color);
ST7735_FillRectangle(x, y, 1, h, border_color);
ST7735_FillRectangle(x + w - 1, y, 1, h, border_color);
// bar
uint16_t bar_width = (w - 2) * current / total;
ST7735_FillRectangle(x + 1, y + 1, bar_width, h - 2, fill_color);
ST7735_FillRectangle(x + bar_width + 1, y + 1, (w - 2 - bar_width), h - 2, ST7735_BLACK);
}
void ui_com_vol_bar(uint8_t clear) {
uint16_t off_x = 1;
uint16_t off_y = ST7735_HEIGHT - 33;
if (clear) {
ST7735_FillRectangle(off_x, off_y, ST7735_WIDTH - 2, 16, ST7735_BLACK);
}
uint16_t color_skyblue = ST7735_COLOR565(0, 0x7F, 0xFF);
// text, 32x16
off_x = off_x + (32 - bmf_get_text_width(font_unifont_8x16, u8str("VOL"), 3)) / 2;
bmf_draw_text(font_unifont_8x16, u8str("VOL"), 3, off_x, off_y, 32, 16, color_skyblue);
// bar
off_x = 1 + 32;
if (global_data.flag & G_FL_MUTE) {
color_skyblue = ST7735_COLOR565(0x20, 0x20, 0x20);
// ui_com_progress_bar(33, off_y + 2, ST7735_WIDTH - 34 - 3, 13, ST7735_WHITE, ST7735_COLOR565(0x20, 0x20, 0x20), G_VOLUMN_MAX, G_VOLUMN_MAX);
} else {
// ui_com_progress_bar(33, off_y + 2, ST7735_WIDTH - 34 - 3, 13, ST7735_WHITE, color_skyblue, global_data.volumn, G_VOLUMN_MAX);
}
ui_com_progress_bar(33, off_y + 2, ST7735_WIDTH - 34 - 3, 13, ST7735_WHITE, color_skyblue, global_data.volumn, G_VOLUMN_MAX);
}
void ui_com_sig_bar(uint8_t clear) {
uint16_t off_x = 1;
uint16_t off_y = ST7735_HEIGHT - 17;
if (clear) {
ST7735_FillRectangle(off_x, off_y, ST7735_WIDTH - 2, 16, ST7735_BLACK);
}
// text, 32x16
off_x = off_x + (32 - bmf_get_text_width(font_unifont_8x16, u8str("SIG"), 3)) / 2;
bmf_draw_text(font_unifont_8x16, u8str("SIG"), 3, off_x, off_y, 32, 16, ST7735_GREEN);
// bar
off_x = 1 + 32;
ui_com_progress_bar(33, off_y + 1, ST7735_WIDTH - 34 - 3, 13, ST7735_WHITE, ST7735_GREEN, global_data.signal, G_RSSI_MAX);
}
/* 图标 */
void icon_stereo() {
mimg_Area area = mimg_get_tile_area(IMG_STEREO, 1, 1, 0);
// margin 1px from left top border
if (global_data.flag & G_FL_MONO) {
ST7735_FillRectangle(8, 25, area.w, area.h, ST7735_BLACK);
} else {
mimg_draw_with_bg(ST7735_DrawPixel, 8, 25, ST7735_YELLOW, ST7735_BLACK, IMG_STEREO, area);
}
}
/* 供外部调用的方法 */
void ui_screen_main() {
ST7735_FillScreen(ST7735_BLACK);
ui_com_main_border();
ui_com_title_bar(0, u8str("Radio"), 5);
ui_com_fm_am(0);
ui_com_freq_digital(0, 0);
ui_com_vol_bar(0);
ui_com_sig_bar(0);
icon_stereo();
}
void ui_screen_main_animation() {
// 绘制闪烁效果
if ((global_data.point_mode & G_PMOD_MODE_MASK) && (global_data.point_mode & G_PMOD_PMOVE_MASK)) {
uint8_t blink_state = (ticks_ms() / UI_BLINK_MS) % 2;
uint8_t blink_state2 = !(global_data.point_mode & G_PMOD_PBLINK_MASK);
uint8_t blink_state3 = (global_data.point_mode & G_PMOD_PBLINK2_MASK) ? 1 : 0;
if ((blink_state ^ blink_state2) ^ blink_state3) {
ui_com_freq_digital(1, 1);
}
}
}