bool TextConsole::feed(int key) { // interprets a keycode and perform the action (or write a letter) RowPtr r; LinkList<Row> &list = rows; LinkList<Row>::iterator it = std::find(list.begin(), list.end(), cur_row); switch(key) { case KEY_NEWLINE: case KEY_ENTER: r = MakeShared<Row>(); if(it != list.end()) ++it; list.insert(it, r); if(cur_row->pos < cur_row->len) { // if cursor is not at the end of the row move_string(r, cur_row, cur_row->len - cur_row->pos); } cur_y++; // scrolling if(cur_y>h) { it = std::find(list.begin(), list.end(), vis_row_in); if(it != list.end() && (++it) != list.end()) { vis_row_in = *it; } else { vis_row_in = NULL; } cur_y = h; } // else refresh_below(); cur_row = r; cur_x = 0; refresh(); break; case KEY_CTRL_L: refresh(); break; case KEY_BACKSPACE_ASCII: case KEY_BACKSPACE: case KEY_BACKSPACE_APPLE: case KEY_BACKSPACE_SOMETIMES: cur_row->backspace(); if(cur_x > 0) { cur_x--; // backwards with cursor refresh_current(); } else // backspace at the beginning of a row if(it != list.begin()) { // there is an upper row r = *(--it); // upper row is empty, just delete it if(r->len <1) { list.erase(it); cur_y--; // upper row is not empty, append to end } else { r->pos = r->len; move_string(r, cur_row, cur_row->len); // delete current row (now empty) list.erase(++it); cur_y--; cur_row = r; } if(cur_y <1) { // we are up in the screen vis_row_in = cur_row; cur_y = 0; refresh(); } else { // or there is more up // so delete a row // cur_row->rem(); // delete cur_row; // move cursor up one line // cur_y--; // refresh_below(); refresh(); } cur_x = r->pos; } break; case KEY_TAB: if(cur_x < w) cur_x += 8; if(cur_x > w) cur_x = w; break; case KEY_LEFT: if(cur_x<=0) break; cur_x--; cur_row->pos--; break; case KEY_RIGHT: if(cur_x >= w) break; if(cur_row->pos >= cur_row->len) break; cur_x++; cur_row->pos++; break; case KEY_UP: if(cur_y>0) { cur_y--; cur_row = *(--it); if(cur_x > cur_row->len) cur_x = cur_row->len; cur_row->pos = cur_x; } else { // scroll if(it == list.begin()) break; vis_row_in = cur_row = *(--it); refresh(); } break; case KEY_DOWN: if(cur_y<h) { if(it != list.end() && (++it) != list.end()) { cur_y++; cur_row = *it; // cursor positioning if(cur_x > cur_row->len) cur_x = cur_row->len; cur_row->pos = cur_x; // } } else { // scrolling if(it == list.end() || (++it) == list.end()) break; cur_row = *it; // scroll down the pointer to upper row it = std::find(list.begin(), list.end(), vis_row_in); vis_row_in = *(++it); refresh(); } break; default: // insert a new char // fits in widget width? if(cur_x < w) { cur_row->insert_char(key); refresh_current(); cur_x++; } // else wrap to next line (TODO) break; } return true; }
bool TextConsole::feed(int key) { // interprets a keycode and perform the action (or write a letter) Row *r; switch(key) { case KEY_NEWLINE: case KEY_ENTER: r = new Row(); rows.insert_after(r, cur_row); if(cur_row->pos < cur_row->len) { // if cursor is not at the end of the row move_string(r, cur_row, cur_row->len - cur_row->pos); } cur_y++; // scrolling if(cur_y>h) { vis_row_in = (Row*) vis_row_in->next; cur_y = h; } // else refresh_below(); cur_row = r; cur_x = 0; refresh(); break; case KEY_CTRL_L: refresh(); break; case KEY_BACKSPACE_ASCII: case KEY_BACKSPACE: case KEY_BACKSPACE_APPLE: case KEY_BACKSPACE_SOMETIMES: cur_row->backspace(); if(cur_x > 0) { cur_x--; // backwards with cursor refresh_current(); } else // backspace at the beginning of a row if(cur_row->prev) { // there is an upper row r = (Row*) cur_row->prev; // upper row is empty, just delete it if(r->len <1) { r->rem(); delete r; cur_y--; // upper row is not empty, append to end } else { r->pos = r->len; move_string(r, cur_row, cur_row->len); // delete current row (now empty) cur_row->rem(); delete cur_row; cur_y--; cur_row = r; } if(cur_y <1) { // we are up in the screen vis_row_in = cur_row; cur_y = 0; refresh(); } else { // or there is more up // so delete a row // cur_row->rem(); // delete cur_row; // move cursor up one line // cur_y--; // refresh_below(); refresh(); } cur_x = r->pos; } break; case KEY_TAB: if(cur_x < w) cur_x += 8; if(cur_x > w) cur_x = w; break; case KEY_LEFT: if(cur_x<=0) break; cur_x--; cur_row->pos--; break; case KEY_RIGHT: if(cur_x >= w) break; if(cur_row->pos >= cur_row->len) break; cur_x++; cur_row->pos++; break; case KEY_UP: if(cur_y>0) { cur_y--; cur_row = (Row*) cur_row->prev; if(cur_x > cur_row->len) cur_x = cur_row->len; cur_row->pos = cur_x; } else { // scroll if(!cur_row->prev) break; vis_row_in = cur_row = (Row*) cur_row->prev; refresh(); } break; case KEY_DOWN: if(cur_y<h) { if(cur_row->next) { cur_y++; cur_row = (Row*) cur_row->next; // cursor positioning if(cur_x > cur_row->len) cur_x = cur_row->len; cur_row->pos = cur_x; // } } else { // scrolling if(!cur_row->next) break; cur_row = (Row*) cur_row->next; // scroll down the pointer to upper row vis_row_in = (Row*) vis_row_in->next; refresh(); } break; default: // insert a new char // fits in widget width? if(cur_x < w) { cur_row->insert_char(key); refresh_current(); cur_x++; } // else wrap to next line (TODO) break; } return true; }