uart: merge rx terminal into tx terminal

* RX should send each key directly, instead of providing cook mode
This commit is contained in:
Zihao Yu 2024-01-11 00:20:29 +08:00
parent 8179e010a6
commit d2b8a0e380
5 changed files with 43 additions and 59 deletions

View File

@ -9,7 +9,9 @@ private:
std::vector<uint8_t *> lines;
int cursor_x, cursor_y; // cursor_y start with all history when scrolling is supported
bool is_cursor_visible;
bool is_focus;
SDL_Texture *cursor_texture;
SDL_Texture *get_focus_cursor_texture;
int screen_y;
bool dirty_screen;
bool *dirty_line;
@ -32,6 +34,7 @@ public:
void feed_str(const char *s);
void clear();
void set_cursor_visibility(bool v);
void set_focus(bool v);
void update_gui();
};

View File

@ -7,14 +7,12 @@
class UART : public Component{
private:
Term *tx_term, *rx_term;
Term *term;
int tx_state, rx_state;
uint16_t divisor;
uint8_t tx_data, rx_data;
std::string rx_input;
std::string rx_sending_str;
static constexpr const char *rx_input_prompt = "(Press Enter to issue): ";
bool tx_update_gui, rx_update_gui;
bool need_update_gui;
uint8_t *p_tx;
public:
UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h);
@ -26,7 +24,7 @@ public:
void tx_receive();
void rx_send();
void rx_getchar(uint8_t ch);
void rx_term_focus(bool v);
void term_focus(bool v);
};
#endif

View File

@ -4,28 +4,28 @@
extern std::vector<Component *> components;
void uart_rx_getchar(uint8_t ch);
void uart_rx_term_focus(bool v);
void uart_term_focus(bool v);
void kb_push_key(uint8_t scancode, bool is_keydown);
static bool focus_uart_rx_term = false;
static bool uart_term_get_focus = false;
static void mousedown_handler(const SDL_Event &ev) {
int x_pos = ev.button.x;
int y_pos = ev.button.y;
bool click_uart_rx_term = false;
bool click_uart_term = false;
for (auto i : components) {
if (i->in_rect(x_pos, y_pos)) {
switch (i->get_component_type()) {
case BUTTON_TYPE: pin_poke(i->get_pin(), 1); break;
case SWITCH_TYPE: pin_poke(i->get_pin(), i->get_state() ^ 1); break;
case UART_TYPE: click_uart_rx_term = true; break;
case UART_TYPE: click_uart_term = true; break;
}
}
}
if (focus_uart_rx_term ^ click_uart_rx_term) {
if (click_uart_rx_term) SDL_StartTextInput();
if (uart_term_get_focus ^ click_uart_term) {
if (click_uart_term) SDL_StartTextInput();
else SDL_StopTextInput();
focus_uart_rx_term = click_uart_rx_term;
uart_rx_term_focus(focus_uart_rx_term);
uart_term_get_focus = click_uart_term;
uart_term_focus(uart_term_get_focus);
}
}
@ -52,15 +52,15 @@ void read_event() {
case SDL_MOUSEBUTTONDOWN: mousedown_handler(ev); break;
case SDL_MOUSEBUTTONUP: mouseup_handler(ev); break;
case SDL_KEYDOWN:
if (focus_uart_rx_term) {
if (uart_term_get_focus) {
switch (ev.key.keysym.sym) {
case SDLK_RETURN: uart_rx_getchar('\n'); break;
case SDLK_BACKSPACE: uart_rx_getchar('\b'); break;
}
}
case SDL_KEYUP:
if (!focus_uart_rx_term) kb_push_key(ev.key.keysym.scancode, ev.key.type == SDL_KEYDOWN);
if (!uart_term_get_focus) kb_push_key(ev.key.keysym.scancode, ev.key.type == SDL_KEYDOWN);
break;
case SDL_TEXTINPUT: if (focus_uart_rx_term) uart_rx_getchar(ev.text.text[0]); break;
case SDL_TEXTINPUT: if (uart_term_get_focus) uart_rx_getchar(ev.text.text[0]); break;
}
}

View File

@ -8,7 +8,9 @@ Term::Term(SDL_Renderer *r, int x, int y, int w, int h):
h_in_char = region.h / CH_HEIGHT;
uint8_t *l = add_line();
cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0x10, 0x10, 0x10);
get_focus_cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0xff, 0x00, 0xff);
is_cursor_visible = true;
is_focus = false;
clear_screen();
dirty_line = new bool[h_in_char];
dirty_char = new bool[w_in_char * h_in_char];
@ -35,6 +37,12 @@ void Term::set_cursor_visibility(bool v) {
if (update_cursor_gui) draw_cursor();
}
void Term::set_focus(bool v) {
bool update_cursor_gui = is_focus ^ v;
is_focus = v;
if (update_cursor_gui) draw_cursor();
}
void Term::clear() {
while (lines.size() > 1) {
delete [] lines.back();
@ -123,7 +131,8 @@ void Term::draw_cursor() {
rect.w = CH_WIDTH, rect.h = CH_HEIGHT;
rect.y += CH_HEIGHT * y;
rect.x += CH_WIDTH * x;
SDL_Texture *t = is_cursor_visible ? cursor_texture : ch2texture_term(' ');
SDL_Texture *t = is_cursor_visible ? (is_focus ? get_focus_cursor_texture :
cursor_texture) : ch2texture_term(' ');
SDL_RenderCopy(renderer, t, NULL, &rect);
set_redraw();
}

View File

@ -8,15 +8,13 @@ static UART* uart = NULL;
int16_t uart_divisor_cnt = 0;
bool is_uart_rx_idle = true;
UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h):
Component(rend, cnt, init_val, ct),
tx_state(0), rx_state(0), divisor(16), tx_update_gui(false) {
tx_term = new Term(rend, x, y, w, h);
rx_term = new Term(rend, x, y + h + 1, w, CH_HEIGHT);
tx_state(0), rx_state(0), divisor(16), need_update_gui(false) {
term = new Term(rend, x, y, w, h);
SDL_Rect *rect_ptr = new SDL_Rect; // rx terminal
*rect_ptr = (SDL_Rect){x, y + h + 1, w, CH_HEIGHT};
SDL_Rect *rect_ptr = new SDL_Rect;
*rect_ptr = (SDL_Rect){x, y, w, h};
set_rect(rect_ptr, 0);
uart_divisor_cnt = divisor - 1;
@ -24,17 +22,11 @@ UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int
assert(len == 0 || len == 1); // either unbound or bound to 1 bit signal
p_tx = (uint8_t *)pin_array[UART_TX].ptr;
rx_term->feed_str(rx_input_prompt);
rx_term->set_cursor_visibility(false);
rx_input = "";
rx_sending_str = "";
SDL_SetRenderDrawColor(rend, 0x00, 0x00, 0x00, 0);
SDL_RenderDrawLine(rend, x, y + h, x + w, y + h);
SDL_RenderDrawLine(rend, x, y + h + 1 + CH_HEIGHT, x + w, y + h + 1 + CH_HEIGHT);
SDL_SetRenderDrawColor(rend, 0xff, 0xff, 0xff, 0);
rx_update_gui = true;
rx_sending_str = "";
pin_poke(UART_RX, 1);
}
@ -60,8 +52,8 @@ void UART::tx_receive() {
} else if (tx_state == 9) {
if (tx) { // stop bit
tx_state = 0;
tx_term->feed_ch(tx_data);
tx_update_gui = true;
term->feed_ch(tx_data);
need_update_gui = true;
}
}
}
@ -88,46 +80,28 @@ void UART::rx_send() {
}
void UART::rx_getchar(uint8_t ch) {
if (ch == '\b') {
if (rx_input.empty()) return;
rx_input.pop_back();
rx_term->backspace(true);
} else {
rx_input += ch;
if (ch == '\n') {
rx_sending_str += rx_input;
is_uart_rx_idle = false;
rx_term->clear();
rx_term->feed_str(rx_input_prompt);
rx_input = "";
}
else { rx_term->feed_ch(ch); }
}
rx_update_gui = true;
rx_sending_str += ch;
is_uart_rx_idle = false;
}
void UART::update_state() {
if (tx_update_gui) {
if (need_update_gui) {
static uint64_t last = 0;
uint64_t now = nvboard_get_time();
if (now - last > 1000000 / UART_TX_FPS) {
last = now;
tx_update_gui = false;
tx_term->update_gui();
need_update_gui = false;
term->update_gui();
}
}
if (rx_update_gui) {
rx_update_gui = false;
rx_term->update_gui();
}
}
void UART::set_divisor(uint16_t d) {
divisor = d;
}
void UART::rx_term_focus(bool v) {
rx_term->set_cursor_visibility(v);
void UART::term_focus(bool v) {
term->set_focus(v);
}
static void init_render_local(SDL_Renderer *renderer) {
@ -173,6 +147,6 @@ void uart_rx_getchar(uint8_t ch) {
uart->rx_getchar(ch);
}
void uart_rx_term_focus(bool v) {
uart->rx_term_focus(v);
void uart_term_focus(bool v) {
uart->term_focus(v);
}