static void view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, int linecount) { int realcount; view_bookmarks_check(view, line); if (view->buffer->cur_line == line) { /* the last line is being removed */ LINE_REC *prevline; prevline = view->buffer->first_line == line ? NULL : textbuffer_line_last(view->buffer); view->cache->last_linecount = prevline == NULL ? 0 : view_get_linecount(view, prevline); } if (view->buffer->first_line == line) { /* first line in the buffer - this is the most commonly removed line.. */ if (view->bottom_startline == line) { /* very small scrollback.. */ view->bottom_startline = view->bottom_startline->next; view->bottom_subline = 0; } if (view->startline == line) { /* removing the first line in screen */ int is_last = view->startline->next == NULL; realcount = view_scroll(view, &view->startline, &view->subline, linecount, FALSE); view->ypos -= realcount; view->empty_linecount += linecount-realcount; if (is_last == 1) view->startline = NULL; } } else { if (textbuffer_line_exists_after(view->bottom_startline, line)) { realcount = view_scroll(view, &view->bottom_startline, &view->bottom_subline, -linecount, FALSE); view->empty_linecount += linecount-realcount; } if (textbuffer_line_exists_after(view->startline, line)) { view_remove_line_update_startline(view, line, linecount); } } view->bottom = view_is_bottom(view); if (view->bottom) view->more_text = FALSE; if (view->window != NULL) term_refresh(view->window); }
static void view_remove_line_update_startline(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, int linecount) { int scroll; if (view->startline == line) { view->startline = view->startline->prev != NULL ? view->startline->prev : view->startline->next; view->subline = 0; } else { scroll = view->height - view_get_lines_height(view, view->startline, view->subline, line); if (scroll > 0) { view_scroll(view, &view->startline, &view->subline, -scroll, FALSE); } } /* FIXME: this is slow and unnecessary, but it's easy and really works :) */ textbuffer_view_init_ypos(view); if (textbuffer_line_exists_after(view->startline, line)) view->ypos -= linecount; }
/* Scroll the view up/down */ void textbuffer_view_scroll(TEXT_BUFFER_VIEW_REC *view, int lines) { int count; g_return_if_fail(view != NULL); count = view_scroll(view, &view->startline, &view->subline, lines, TRUE); view->ypos += lines < 0 ? count : -count; view->bottom = view_is_bottom(view); if (view->bottom) view->more_text = FALSE; if (view->window != NULL) term_refresh(view->window); }
static void view_insert_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) { int linecount, ypos, subline; if (!view->bottom) view->more_text = TRUE; if (view->bottom_startline == NULL) { view->startline = view->bottom_startline = view->buffer->first_line; } if (view->buffer->cur_line != line && !textbuffer_line_exists_after(view->bottom_startline, line)) return; linecount = view->cache->last_linecount; view->ypos += linecount; if (view->empty_linecount > 0) { view->empty_linecount -= linecount; if (view->empty_linecount >= 0) linecount = 0; else { linecount = -view->empty_linecount; view->empty_linecount = 0; } } if (linecount > 0) { view_scroll(view, &view->bottom_startline, &view->bottom_subline, linecount, FALSE); } if (view->bottom) { if (view->scroll && view->ypos >= view->height) { linecount = view->ypos-view->height+1; view_scroll(view, &view->startline, &view->subline, linecount, FALSE); view->ypos -= linecount; } else { view->bottom = view_is_bottom(view); } if (view->window != NULL) { ypos = view->ypos+1 - view->cache->last_linecount; if (ypos >= 0) subline = 0; else { subline = -ypos; ypos = 0; } if (ypos < view->height) { view_line_draw(view, line, subline, ypos, view->height - ypos); } } } if (view->window != NULL) term_refresh(view->window); }
/* Resize the view. */ void textbuffer_view_resize(TEXT_BUFFER_VIEW_REC *view, int width, int height) { int linecount; g_return_if_fail(view != NULL); g_return_if_fail(width > 0); if (view->width != width) { /* line cache needs to be recreated */ textbuffer_cache_unref(view->cache); view->cache = textbuffer_cache_get(view->siblings, width); } view->width = width > 10 ? width : 10; view->height = height > 1 ? height : 1; if (view->buffer->first_line == NULL) { view->empty_linecount = height; return; } textbuffer_view_init_bottom(view); /* check that we didn't scroll lower than bottom startline.. */ if (textbuffer_line_exists_after(view->bottom_startline->next, view->startline)) { view->startline = view->bottom_startline; view->subline = view->bottom_subline; } else if (view->startline == view->bottom_startline && view->subline > view->bottom_subline) { view->subline = view->bottom_subline; } else { /* make sure the subline is still in allowed range */ linecount = view_get_linecount(view, view->startline); if (view->subline > linecount) view->subline = linecount; } textbuffer_view_init_ypos(view); if (view->bottom && !view_is_bottom(view)) { /* we scrolled to far up, need to get down. go right over the empty lines if there's any */ view->startline = view->bottom_startline; view->subline = view->bottom_subline; if (view->empty_linecount > 0) { view_scroll(view, &view->startline, &view->subline, -view->empty_linecount, FALSE); } textbuffer_view_init_ypos(view); } view->bottom = view_is_bottom(view); if (view->bottom) { /* check if we left empty space at the bottom.. */ linecount = view_get_linecount_all(view, view->startline) - view->subline; if (view->empty_linecount < view->height-linecount) view->empty_linecount = view->height-linecount; view->more_text = FALSE; } view->dirty = TRUE; }