3862
As the finishing touch on commit 3860, completely decouple the termbox API between moving the cursor and printing at the cursor.
This commit is contained in:
parent
b6fa632e2f
commit
537ad74ccc
|
@ -127,7 +127,7 @@ case PRINT_CHARACTER_TO_DISPLAY: {
|
|||
bg_color = ingredients.at(2).at(0);
|
||||
if (bg_color == 0) bg_color = TB_BLACK;
|
||||
}
|
||||
tb_change_cell(Display_column, Display_row, c, color, bg_color);
|
||||
tb_print(c, color, bg_color);
|
||||
// track row and column, mimicking what happens on screen
|
||||
if (c == '\n') {
|
||||
if (Display_row < height-1) ++Display_row; // otherwise we scroll and Display_row remains unchanged
|
||||
|
@ -145,7 +145,6 @@ case PRINT_CHARACTER_TO_DISPLAY: {
|
|||
if (Display_row < height-1) ++Display_row;
|
||||
}
|
||||
}
|
||||
tb_set_cursor(Display_column, Display_row);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -435,9 +434,8 @@ case CLEAR_LINE_ON_DISPLAY: {
|
|||
case CLEAR_LINE_ON_DISPLAY: {
|
||||
CHECK_SCREEN;
|
||||
int width = tb_width();
|
||||
for (int x = Display_column; x < width; ++x) {
|
||||
tb_change_cell(x, Display_row, ' ', TB_WHITE, TB_BLACK);
|
||||
}
|
||||
for (int x = Display_column; x < width; ++x)
|
||||
cout << ' ';
|
||||
tb_set_cursor(Display_column, Display_row);
|
||||
break;
|
||||
}
|
||||
|
@ -460,9 +458,10 @@ case CLEAR_DISPLAY_FROM: {
|
|||
int right = ingredients.at(3).at(0);
|
||||
int height=tb_height();
|
||||
for (/*nada*/; row < height; ++row, column=left) { // start column from left in every inner loop except first
|
||||
for (/*nada*/; column <= right; ++column) {
|
||||
tb_change_cell(column, row, ' ', TB_WHITE, TB_BLACK);
|
||||
}
|
||||
tb_set_cursor(column, row);
|
||||
for (/*nada*/; column <= right; ++column)
|
||||
cout << ' ';
|
||||
}
|
||||
tb_set_cursor(Display_column, Display_row);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ void start_trace_browser() {
|
|||
Visible.insert(i);
|
||||
}
|
||||
tb_init();
|
||||
tb_clear();
|
||||
Display_row = Display_column = 0;
|
||||
Top_of_screen = 0;
|
||||
refresh_screen_rows();
|
||||
|
@ -271,11 +272,10 @@ bool start_search_editor(search_direction dir) {
|
|||
const int bottom_screen_line = tb_height()-1;
|
||||
// run a little editor just in the last line of the screen
|
||||
clear_line(bottom_screen_line);
|
||||
tb_set_cursor(0, bottom_screen_line);
|
||||
int col = 0; // screen column of cursor on bottom line. also used to update pattern.
|
||||
tb_change_cell(col, bottom_screen_line, '/', TB_WHITE, TB_BLACK);
|
||||
++col;
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
tb_print('/', TB_WHITE, TB_BLACK);
|
||||
++col;
|
||||
string pattern;
|
||||
while (true) {
|
||||
int key = read_key();
|
||||
|
@ -311,45 +311,46 @@ bool start_search_editor(search_direction dir) {
|
|||
}
|
||||
else if (key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2) {
|
||||
if (col > /*slash*/1) {
|
||||
assert(col <= SIZE(pattern)+1);
|
||||
--col;
|
||||
// update pattern
|
||||
pattern.erase(col-/*slash*/1, /*len*/1);
|
||||
// update screen
|
||||
if (col > SIZE(pattern)) {
|
||||
tb_change_cell(col, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
|
||||
}
|
||||
else {
|
||||
assert(col <= SIZE(pattern));
|
||||
for (int x = col; x < SIZE(pattern)+/*skip slash*/1; ++x)
|
||||
tb_change_cell(x, bottom_screen_line, pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
|
||||
tb_change_cell(SIZE(pattern)+/*skip slash*/1, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
|
||||
}
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
for (int x = col; x < SIZE(pattern)+/*skip slash*/1; ++x)
|
||||
tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
|
||||
tb_print(' ', TB_WHITE, TB_BLACK);
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
}
|
||||
}
|
||||
else if (key == TB_KEY_CTRL_K) {
|
||||
int old_pattern_size = SIZE(pattern);
|
||||
pattern.erase(col-/*slash*/1, SIZE(pattern) - (col-/*slash*/1));
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
for (int x = col; x < old_pattern_size+/*slash*/1; ++x)
|
||||
tb_change_cell(x, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
|
||||
tb_print(' ', TB_WHITE, TB_BLACK);
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
}
|
||||
else if (key == TB_KEY_CTRL_U) {
|
||||
int old_pattern_size = SIZE(pattern);
|
||||
pattern.erase(0, col-/*slash*/1);
|
||||
col = /*skip slash*/1;
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
for (int x = /*slash*/1; x < SIZE(pattern)+/*skip slash*/1; ++x)
|
||||
tb_change_cell(x, bottom_screen_line, pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
|
||||
tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
|
||||
for (int x = SIZE(pattern)+/*slash*/1; x < old_pattern_size+/*skip slash*/1; ++x)
|
||||
tb_change_cell(x, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
|
||||
tb_set_cursor(/*start of pattern skipping slash*/1, bottom_screen_line);
|
||||
tb_print(' ', TB_WHITE, TB_BLACK);
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
}
|
||||
else if (key < 128) { // ascii only
|
||||
// update pattern
|
||||
char c = static_cast<char>(key);
|
||||
assert(col-1 >= 0);
|
||||
assert(col-1 <= SIZE(pattern));
|
||||
pattern.insert(col-/*slash*/1, /*num*/1, c);
|
||||
// update screen
|
||||
for (int x = col; x < SIZE(pattern)+/*skip slash*/1; ++x)
|
||||
tb_change_cell(x, bottom_screen_line, pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
|
||||
tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
|
||||
++col;
|
||||
tb_set_cursor(col, bottom_screen_line);
|
||||
}
|
||||
|
@ -391,8 +392,10 @@ void search_previous(const string& pat) {
|
|||
}
|
||||
|
||||
void clear_line(int screen_row) {
|
||||
tb_set_cursor(0, screen_row);
|
||||
for (int col = 0; col < tb_width(); ++col)
|
||||
tb_change_cell(col, screen_row, ' ', TB_WHITE, TB_BLACK);
|
||||
tb_print(' ', TB_WHITE, TB_BLACK);
|
||||
tb_set_cursor(0, screen_row);
|
||||
}
|
||||
|
||||
// update Trace_indices for each screen_row on the basis of Top_of_screen and Visible
|
||||
|
@ -450,6 +453,7 @@ void render_line(int screen_row, const string& s, bool cursor_line) {
|
|||
int color = TB_WHITE;
|
||||
int background_color = cursor_line ? /*subtle grey*/240 : TB_BLACK;
|
||||
vector<pair<size_t, size_t> > highlight_ranges = find_all_occurrences(s, Current_search_pattern);
|
||||
tb_set_cursor(0, screen_row);
|
||||
for (col = 0; col < tb_width() && col+Left_of_screen < SIZE(s); ++col) {
|
||||
char c = s.at(col+Left_of_screen); // todo: unicode
|
||||
if (c == '\n') c = ';'; // replace newlines with semi-colons
|
||||
|
@ -457,12 +461,12 @@ void render_line(int screen_row, const string& s, bool cursor_line) {
|
|||
if (c == '\1') { color = /*red*/1; c = ' '; }
|
||||
if (c == '\2') { color = TB_WHITE; c = ' '; }
|
||||
if (in_range(highlight_ranges, col+Left_of_screen))
|
||||
tb_change_cell(col, screen_row, c, TB_BLACK, /*yellow*/11);
|
||||
tb_print(c, TB_BLACK, /*yellow*/11);
|
||||
else
|
||||
tb_change_cell(col, screen_row, c, color, background_color);
|
||||
tb_print(c, color, background_color);
|
||||
}
|
||||
for (; col < tb_width(); ++col)
|
||||
tb_change_cell(col, screen_row, ' ', TB_WHITE, background_color);
|
||||
tb_print(' ', TB_WHITE, background_color);
|
||||
}
|
||||
|
||||
vector<pair<size_t, size_t> > find_all_occurrences(const string& s, const string& pat) {
|
||||
|
|
|
@ -45,7 +45,6 @@ static uint16_t foreground = TB_WHITE;
|
|||
static void update_size(void);
|
||||
static void update_term_size(void);
|
||||
static void send_attr(uint16_t fg, uint16_t bg);
|
||||
static void send_char(int x, int y, uint32_t c);
|
||||
static void send_clear(void);
|
||||
static void sigwinch_handler(int xxx);
|
||||
static int wait_fill_event(struct tb_event *event, struct timeval *timeout);
|
||||
|
@ -99,6 +98,7 @@ int tb_init(void)
|
|||
bytebuffer_puts(&output_buffer, funcs[T_ENTER_KEYPAD]);
|
||||
bytebuffer_puts(&output_buffer, funcs[T_ENTER_MOUSE]);
|
||||
bytebuffer_puts(&output_buffer, funcs[T_ENTER_BRACKETED_PASTE]);
|
||||
bytebuffer_flush(&output_buffer, inout);
|
||||
|
||||
update_term_size();
|
||||
return 0;
|
||||
|
@ -130,11 +130,20 @@ int tb_is_active(void)
|
|||
return termw != -1;
|
||||
}
|
||||
|
||||
void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg)
|
||||
void tb_print(uint32_t ch, uint16_t fg, uint16_t bg)
|
||||
{
|
||||
assert(termw != -1);
|
||||
send_attr(fg, bg);
|
||||
send_char(x, y, ch);
|
||||
if (ch == 0) {
|
||||
// replace 0 with whitespace
|
||||
bytebuffer_puts(&output_buffer, " ");
|
||||
}
|
||||
else {
|
||||
char buf[7];
|
||||
int bw = tb_utf8_unicode_to_char(buf, ch);
|
||||
buf[bw] = '\0';
|
||||
bytebuffer_puts(&output_buffer, buf);
|
||||
}
|
||||
bytebuffer_flush(&output_buffer, inout);
|
||||
}
|
||||
|
||||
|
@ -265,16 +274,6 @@ static void send_attr(uint16_t fg, uint16_t bg)
|
|||
}
|
||||
}
|
||||
|
||||
static void send_char(int x, int y, uint32_t c)
|
||||
{
|
||||
char buf[7];
|
||||
int bw = tb_utf8_unicode_to_char(buf, c);
|
||||
buf[bw] = '\0';
|
||||
tb_set_cursor(x, y);
|
||||
if(!c) buf[0] = ' '; // replace 0 with whitespace
|
||||
bytebuffer_puts(&output_buffer, buf);
|
||||
}
|
||||
|
||||
const char* to_unicode(uint32_t c)
|
||||
{
|
||||
static char buf[7];
|
||||
|
|
|
@ -37,16 +37,16 @@ int tb_is_active(void);
|
|||
int tb_width(void);
|
||||
int tb_height(void);
|
||||
|
||||
/* Clear the internal screen state using either TB_DEFAULT or the
|
||||
* color/attributes set by tb_set_clear_attributes(). */
|
||||
/* Clear the screen using either TB_DEFAULT or the color/attributes set by
|
||||
* tb_set_clear_attributes(). */
|
||||
void tb_clear(void);
|
||||
void tb_set_clear_attributes(uint16_t fg, uint16_t bg);
|
||||
|
||||
/* Move the cursor. Upper-left character is (0, 0). */
|
||||
void tb_set_cursor(int cx, int cy);
|
||||
|
||||
/* Modify a specific cell of the screen. */
|
||||
void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg);
|
||||
/* Modify the screen at the cursor. */
|
||||
void tb_print(uint32_t ch, uint16_t fg, uint16_t bg);
|
||||
|
||||
/*** 2. Controlling keyboard events. */
|
||||
|
||||
|
|
Loading…
Reference in New Issue