ealeon
ealeon

Reputation: 12462

Perl curses: refresh() doesnt delete lines

sub display {
    my @data = @_;
    my $max_row = 0;
    my $max_col = 0;
    getmaxyx($max_row, $max_col);
    clear();                        <------ i dont want to clear everytime

    if ($start_display) {
        my $row   = 0;
        my $color = COLOR_PAIR(1);
        attron($color);

        attroff($color);
        foreach my $line (@data) {
            $color = COLOR_PAIR(1);
            $color = COLOR_PAIR(2) if ($line =~ /waiting/);
            attron($color);
            $line = substr($line, 0, $max_col);
            addstr($row++, 0, $line);
            attroff($color);
            last if ($row >= $max_row - 1);
        }
        $color = COLOR_PAIR(1);
        attron($color);
        attroff($color);
    } else {
        my $dots = '.';
        $dots = $dots x $dot_cnt;
        addstr("Program is starting...$dots");
        $dot_cnt++;
        sleep 1;
    }

    my $color = COLOR_PAIR(1);
    attron($color);
    addstr($max_row-1, 0, $usage);
    attroff($color);

    refresh();     <------ refreshes but doesnt clear 
} ## end sub display

Right now, i am clearing the screen everytime but this is making the screen very choppy. If i get rid of clear() the chopiness goes away but refresh() does not update correctly (i.e. leaves the previously displayed lines as is when some should get deleted)

How do I update the screen properly so that only the changed lines get updated and delete the lines from the screen properly?

Upvotes: 2

Views: 291

Answers (1)

Ben Grimm
Ben Grimm

Reputation: 4371

addstr() will only write through to the length of the string passed to it. In order to avoid remnants, you need to ensure that the string is padded to the width of the window. I would suggest padding the string with spaces in the step where you truncate to $max_col:

$line = substr( $line . " " x $max_col, 0, $max_col );

Or factor it out:

sub addstr_pad { 
    my ( $row, $str, $width ) = @_;
    addstr( $row, 0, substr( $str . " " x $width, 0, $width ) ); 
}
...
addstr_pad( $row++, $line, $max_col );

To ensure that you're clearing any rows that may have had text from the last iteration, include this after iterating over @data:

while( $row <= $max_row ) { 
    addstr( $row++, 0, " " x $max_col )); 
}

You wouldn't necessarily need to clear through $max_row if the length of @data were retained from the previous run.

Upvotes: 1

Related Questions