From 2db7d9222bb57beff0b3f0c44f1e0762ced3fb9f Mon Sep 17 00:00:00 2001 From: gregor herrmann Date: Wed, 4 Oct 2023 21:13:29 +0200 Subject: New upstream version 0.32 --- Build.PL | 2 +- Changes | 9 +++ META.json | 10 +-- META.yml | 10 +-- README | 68 ++++++++-------- lib/Tickit/Widget/Scroller.pm | 121 ++++++++++++++-------------- lib/Tickit/Widget/Scroller/Item/RichText.pm | 19 +++-- lib/Tickit/Widget/Scroller/Item/Text.pm | 16 ++-- t/01item-text.t | 34 +++++++- t/02item-richtext.t | 16 ++-- t/10initial.t | 6 +- 11 files changed, 184 insertions(+), 127 deletions(-) diff --git a/Build.PL b/Build.PL index 4bd5cf4..4e204e9 100644 --- a/Build.PL +++ b/Build.PL @@ -8,7 +8,7 @@ my $build = Module::Build->new( module_name => 'Tickit::Widget::Scroller', requires => { 'perl' => '5.026', # signatures - 'Object::Pad' => '0.74', # 0.73 + bugfix + 'Object::Pad' => '0.800', 'String::Tagged' => 0, 'Tickit::RenderBuffer' => '0.43', # flush_to_term diff --git a/Changes b/Changes index 4850a1f..4e11248 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,14 @@ Revision history for Tickit-Widget-Scroller +0.32 2023-10-02 + [CHANGES] + * Allow items to be specified by index, reverse index, or direct + object reference + * Cache pens used in RichText items for reuse; saves a lot of memory + in big long-running programs + * Updated to Object::Pad v0.800 + * Respect non-breaking spaces when word-wrapping + 0.31 2023-08-30 [CHANGES] * Added `->items` accessor for querying the number of stored items diff --git a/META.json b/META.json index 485add6..7e21624 100644 --- a/META.json +++ b/META.json @@ -16,7 +16,7 @@ "prereqs" : { "runtime" : { "requires" : { - "Object::Pad" : "0.74", + "Object::Pad" : "0.800", "String::Tagged" : "0", "Tickit::Pen" : "0.19", "Tickit::RenderBuffer" : "0.43", @@ -35,15 +35,15 @@ "provides" : { "Tickit::Widget::Scroller" : { "file" : "lib/Tickit/Widget/Scroller.pm", - "version" : "0.31" + "version" : "0.32" }, "Tickit::Widget::Scroller::Item::RichText" : { "file" : "lib/Tickit/Widget/Scroller/Item/RichText.pm", - "version" : "0.31" + "version" : "0.32" }, "Tickit::Widget::Scroller::Item::Text" : { "file" : "lib/Tickit/Widget/Scroller/Item/Text.pm", - "version" : "0.31" + "version" : "0.32" } }, "release_status" : "stable", @@ -53,6 +53,6 @@ ], "x_IRC" : "irc://irc.freenode.net/#tickit" }, - "version" : "0.31", + "version" : "0.32", "x_serialization_backend" : "JSON::PP version 4.07" } diff --git a/META.yml b/META.yml index 09729ce..f380bf2 100644 --- a/META.yml +++ b/META.yml @@ -15,15 +15,15 @@ name: Tickit-Widget-Scroller provides: Tickit::Widget::Scroller: file: lib/Tickit/Widget/Scroller.pm - version: '0.31' + version: '0.32' Tickit::Widget::Scroller::Item::RichText: file: lib/Tickit/Widget/Scroller/Item/RichText.pm - version: '0.31' + version: '0.32' Tickit::Widget::Scroller::Item::Text: file: lib/Tickit/Widget/Scroller/Item/Text.pm - version: '0.31' + version: '0.32' requires: - Object::Pad: '0.74' + Object::Pad: '0.800' String::Tagged: '0' Tickit::Pen: '0.19' Tickit::RenderBuffer: '0.43' @@ -33,5 +33,5 @@ requires: resources: IRC: irc://irc.freenode.net/#tickit license: http://dev.perl.org/licenses/ -version: '0.31' +version: '0.32' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff --git a/README b/README index e959163..e6069e5 100644 --- a/README +++ b/README @@ -101,14 +101,14 @@ METHODS set_on_scrolled - $on_scrolled = $scroller->on_scrolled + $on_scrolled = $scroller->on_scrolled; - $scroller->set_on_scrolled( $on_scrolled ) + $scroller->set_on_scrolled( $on_scrolled ); Return or set the CODE reference to be called when the scroll position is adjusted. - $on_scrolled->( $scroller, $delta ) + $on_scrolled->( $scroller, $delta ); This is invoked by the scroll method, including the scroll_to, scroll_to_top and scroll_to_bottom. In normal cases it will be given @@ -118,7 +118,7 @@ METHODS items - $count = scalar $scroller->items; + $count = $scroller->items; Since version 0.31. @@ -128,7 +128,7 @@ METHODS push - $scroller->push( @items ) + $scroller->push( @items ); Append the given items to the end of the list. @@ -141,7 +141,7 @@ METHODS unshift - $scroller->unshift( @items ) + $scroller->unshift( @items ); Prepend the given items to the beginning of the list. @@ -154,7 +154,7 @@ METHODS shift - @items = $scroller->shift( $count ) + @items = $scroller->shift( $count ); Remove the given number of items from the start of the list and returns them. @@ -168,7 +168,7 @@ METHODS pop - @items = $scroller->pop( $count ) + @items = $scroller->pop( $count ); Remove the given number of items from the end of the list and returns them. @@ -182,7 +182,7 @@ METHODS scroll - $scroller->scroll( $delta ) + $scroller->scroll( $delta ); Move the display up or down by the given $delta amount; with positive moving down. This will be a physical count of displayed lines; if some @@ -191,36 +191,37 @@ METHODS scroll_to - $scroller->scroll_to( $line, $itemidx, $itemline ) + $scroller->scroll_to( $line, $item_or_idx, $itemline ); Moves the display up or down so that display line $line contains line - $itemline of item $itemidx. Any of these counts may be negative to - count backwards from the display lines, items, or lines within the - item. + $itemline of the item; which may be given by object reference or index + number. Any of these counts may be negative to count backwards from the + display lines, items, or lines within the item. scroll_to_top - $scroller->scroll_to_top( $itemidx, $itemline ) + $scroller->scroll_to_top( $item_or_idx, $itemline ); Shortcut for scroll_to to set the top line of display; where $line is - 0. If $itemline is undefined, it will be passed as 0. If $itemidx is - also undefined, it will be passed as 0. Calling this method with no + 0. If $itemline is undefined, it will be passed as 0. If $item_or_idx + is also undefined, it will be passed as 0. Calling this method with no arguments, therefore scrolls to the very top of the display. scroll_to_bottom - $scroller->scroll_to_bottom( $itemidx, $itemline ) + $scroller->scroll_to_bottom( $item_or_idx, $itemline ); Shortcut for scroll_to to set the bottom line of display; where $line - is -1. If $itemline is undefined, it will be passed as -1. If $itemidx - is also undefined, it will be passed as -1. Calling this method with no - arguments, therefore scrolls to the very bottom of the display. + is -1. If $itemline is undefined, it will be passed as -1. If + $item_or_idx is also undefined, it will be passed as -1. Calling this + method with no arguments, therefore scrolls to the very bottom of the + display. line2item - $itemidx = $scroller->line2item( $line ) + $itemidx = $scroller->line2item( $line ); - ( $itemidx, $itemline ) = $scroller->line2item( $line ) + ( $itemidx, $itemline ) = $scroller->line2item( $line ); Returns the item index currently on display at the given line of the window. In list context, also returns the line number within item. If @@ -230,14 +231,15 @@ METHODS item2line - $line = $scroller->item2line( $itemidx, $itemline ) + $line = $scroller->item2line( $item_or_idx, $itemline ); - ( $line, $offscreen ) = $scroller->item2line( $itemidx, $itemline, $count_offscreen ) + ( $line, $offscreen ) = $scroller->item2line( $item_or_idx, $itemline, $count_offscreen ); Returns the display line in the window of the given line of the item at - the given index. $itemidx may be given negative, to count backwards - from the last item. $itemline may be negative to count backward from - the last line of the item. + the given index. $item_or_idx may be an item directly, a non-negative + integer to give its index, or a negative to count backwards from the + last item. $itemline may be negative to count backward from the last + line of the item. In list context, also returns a value describing the offscreen nature of the item. For items fully on display, this value is undef. If the @@ -251,13 +253,13 @@ METHODS lines_above - $count = $scroller->lines_above + $count = $scroller->lines_above; Returns the number of lines of content above the scrolled display. lines_below - $count = $scroller->lines_below + $count = $scroller->lines_below; Returns the number of lines of content below the scrolled display. @@ -265,9 +267,9 @@ METHODS set_gen_bottom_indicator - $scroller->set_gen_top_indicator( $method ) + $scroller->set_gen_top_indicator( $method ); - $scroller->set_gen_bottom_indicator( $method ) + $scroller->set_gen_bottom_indicator( $method ); Accessors for the generators for the top and bottom indicator text. If set, each should be a CODE reference or method name on the scroller @@ -277,14 +279,14 @@ METHODS in an indicator window. This will be a small one-line window displayed at the top right or bottom right corner of the Scroller's window. - $text = $scroller->$method() + $text = $scroller->$method(); The ability to pass method names allows subclasses to easily implement custom logic as methods without having to capture a closure. update_indicators - $scroller->update_indicators + $scroller->update_indicators; Calls any defined generators for indicator text, and updates the indicator windows with the returned text. This may be useful if the diff --git a/lib/Tickit/Widget/Scroller.pm b/lib/Tickit/Widget/Scroller.pm index b2f374c..57de1a8 100644 --- a/lib/Tickit/Widget/Scroller.pm +++ b/lib/Tickit/Widget/Scroller.pm @@ -5,9 +5,9 @@ use v5.26; # signatures use warnings; -use Object::Pad 0.73 ':experimental(adjust_params init_expr)'; +use Object::Pad 0.800 ':experimental(adjust_params)'; -package Tickit::Widget::Scroller 0.31; +package Tickit::Widget::Scroller 0.32; class Tickit::Widget::Scroller :strict(params) :isa(Tickit::Widget); @@ -188,15 +188,31 @@ ADJUST :params ( method cols () { 1 } method lines () { 1 } -method _item ( $idx ) +method _itemidx_for ( $item_or_idx ) { - return $_items[$idx]; + if( ref $item_or_idx ) { + my $idx; + $_items[$_] == $item_or_idx and ( $idx = $_ ), last for 0 .. $#_items; + croak '$item_or_idx is not an item in the Scroller' if !defined $idx; + return $idx; + } + + if( $item_or_idx < 0 ) { + $item_or_idx += @_items; + + croak '$item_or_idx out of bounds' if $item_or_idx < 0; + } + else { + croak '$item_or_idx out of bounds' if $item_or_idx >= @_items; + } + + return $item_or_idx; } method _itemheight ( $idx ) { return $_itemheights[$idx] if defined $_itemheights[$idx]; - return $_itemheights[$idx] = $self->_item( $idx )->height_for_width( $self->window->cols ); + return $_itemheights[$idx] = $_items[$idx]->height_for_width( $self->window->cols ); } method reshape () @@ -255,14 +271,14 @@ method window_gained ( $win ) =head2 set_on_scrolled - $on_scrolled = $scroller->on_scrolled + $on_scrolled = $scroller->on_scrolled; - $scroller->set_on_scrolled( $on_scrolled ) + $scroller->set_on_scrolled( $on_scrolled ); Return or set the CODE reference to be called when the scroll position is adjusted. - $on_scrolled->( $scroller, $delta ) + $on_scrolled->( $scroller, $delta ); This is invoked by the C method, including the C, C and C. In normal cases it will be given the @@ -275,7 +291,7 @@ clipped if this would scroll past the beginning or end of the display. =head2 items - $count = scalar $scroller->items; + $count = $scroller->items; I @@ -289,7 +305,7 @@ method items { return scalar @_items; } =head2 push - $scroller->push( @items ) + $scroller->push( @items ); Append the given items to the end of the list. @@ -344,7 +360,7 @@ method push ( @more ) =head2 unshift - $scroller->unshift( @items ) + $scroller->unshift( @items ); Prepend the given items to the beginning of the list. @@ -409,7 +425,7 @@ method unshift ( @more ) =head2 shift - @items = $scroller->shift( $count ) + @items = $scroller->shift( $count ); Remove the given number of items from the start of the list and returns them. @@ -450,7 +466,7 @@ method shift ( $count = 1 ) =head2 pop - @items = $scroller->pop( $count ) + @items = $scroller->pop( $count ); Remove the given number of items from the end of the list and returns them. @@ -488,7 +504,7 @@ method pop ( $count = 1 ) =head2 scroll - $scroller->scroll( $delta ) + $scroller->scroll( $delta ); Move the display up or down by the given C<$delta> amount; with positive moving down. This will be a physical count of displayed lines; if some items @@ -582,15 +598,16 @@ REDO: =head2 scroll_to - $scroller->scroll_to( $line, $itemidx, $itemline ) + $scroller->scroll_to( $line, $item_or_idx, $itemline ); Moves the display up or down so that display line C<$line> contains line -C<$itemline> of item C<$itemidx>. Any of these counts may be negative to count -backwards from the display lines, items, or lines within the item. +C<$itemline> of the item; which may be given by object reference or index +number. Any of these counts may be negative to count backwards from the +display lines, items, or lines within the item. =cut -method scroll_to ( $line, $itemidx, $itemline ) +method scroll_to ( $line, $item_or_idx, $itemline ) { my $window = $self->window or return; @@ -605,14 +622,7 @@ method scroll_to ( $line, $itemidx, $itemline ) croak '$line out of bounds' if $line >= $_window_lines; } - if( $itemidx < 0 ) { - $itemidx += @_items; - - croak '$itemidx out of bounds' if $itemidx < 0; - } - else { - croak '$itemidx out of bounds' if $itemidx >= @_items; - } + my $itemidx = $self->_itemidx_for( $item_or_idx ); my $itemheight = $self->_itemheight( $itemidx ); @@ -663,41 +673,41 @@ method scroll_to ( $line, $itemidx, $itemline ) =head2 scroll_to_top - $scroller->scroll_to_top( $itemidx, $itemline ) + $scroller->scroll_to_top( $item_or_idx, $itemline ); Shortcut for C to set the top line of display; where C<$line> is 0. -If C<$itemline> is undefined, it will be passed as 0. If C<$itemidx> is also -undefined, it will be passed as 0. Calling this method with no arguments, +If C<$itemline> is undefined, it will be passed as 0. If C<$item_or_idx> is +also undefined, it will be passed as 0. Calling this method with no arguments, therefore scrolls to the very top of the display. =cut -method scroll_to_top ( $itemidx = 0, $itemline = 0 ) +method scroll_to_top ( $item_or_idx = 0, $itemline = 0 ) { - $self->scroll_to( 0, $itemidx, $itemline ); + $self->scroll_to( 0, $item_or_idx, $itemline ); } =head2 scroll_to_bottom - $scroller->scroll_to_bottom( $itemidx, $itemline ) + $scroller->scroll_to_bottom( $item_or_idx, $itemline ); Shortcut for C to set the bottom line of display; where C<$line> is --1. If C<$itemline> is undefined, it will be passed as -1. If C<$itemidx> is -also undefined, it will be passed as -1. Calling this method with no +-1. If C<$itemline> is undefined, it will be passed as -1. If C<$item_or_idx> +is also undefined, it will be passed as -1. Calling this method with no arguments, therefore scrolls to the very bottom of the display. =cut -method scroll_to_bottom ( $itemidx = -1, $itemline = -1 ) +method scroll_to_bottom ( $item_or_idx = -1, $itemline = -1 ) { - $self->scroll_to( -1, $itemidx, $itemline ); + $self->scroll_to( -1, $item_or_idx, $itemline ); } =head2 line2item - $itemidx = $scroller->line2item( $line ) + $itemidx = $scroller->line2item( $line ); - ( $itemidx, $itemline ) = $scroller->line2item( $line ) + ( $itemidx, $itemline ) = $scroller->line2item( $line ); Returns the item index currently on display at the given line of the window. In list context, also returns the line number within item. If no window has @@ -739,14 +749,14 @@ method line2item ( $line ) =head2 item2line - $line = $scroller->item2line( $itemidx, $itemline ) + $line = $scroller->item2line( $item_or_idx, $itemline ); - ( $line, $offscreen ) = $scroller->item2line( $itemidx, $itemline, $count_offscreen ) + ( $line, $offscreen ) = $scroller->item2line( $item_or_idx, $itemline, $count_offscreen ); Returns the display line in the window of the given line of the item at the -given index. C<$itemidx> may be given negative, to count backwards from the -last item. C<$itemline> may be negative to count backward from the last line -of the item. +given index. C<$item_or_idx> may be an item directly, a non-negative integer +to give its index, or a negative to count backwards from the last item. +C<$itemline> may be negative to count backward from the last line of the item. In list context, also returns a value describing the offscreen nature of the item. For items fully on display, this value is C. If the given line of @@ -759,20 +769,13 @@ lines in the scroller's window for items C<"below">. =cut -method item2line ( $want_itemidx, $want_itemline = 0, $count_offscreen = 0 ) +method item2line ( $want_item_or_idx, $want_itemline = 0, $count_offscreen = 0 ) { my $window = $self->window or return; @_items or return; - if( $want_itemidx < 0 ) { - $want_itemidx += @_items; - - croak '$itemidx out of bounds' if $want_itemidx < 0; - } - else { - croak '$itemidx out of bounds' if $want_itemidx >= @_items; - } + my $want_itemidx = $self->_itemidx_for( $want_item_or_idx ); my $itemheight = $self->_itemheight( $want_itemidx ); @@ -827,7 +830,7 @@ method item2line ( $want_itemidx, $want_itemline = 0, $count_offscreen = 0 ) =head2 lines_above - $count = $scroller->lines_above + $count = $scroller->lines_above; Returns the number of lines of content above the scrolled display. @@ -842,7 +845,7 @@ method lines_above () =head2 lines_below - $count = $scroller->lines_below + $count = $scroller->lines_below; Returns the number of lines of content below the scrolled display. @@ -882,7 +885,7 @@ method render_to_rb ( $rb, $rect ) my $endline = $rect->bottom; while( $line < $endline and $itemidx < @_items ) { - my $item = $self->_item( $itemidx ); + my $item = $_items[$itemidx]; my $itemheight = $self->_itemheight( $itemidx ); my $top = $line; @@ -948,9 +951,9 @@ method on_mouse ( $ev ) =head2 set_gen_bottom_indicator - $scroller->set_gen_top_indicator( $method ) + $scroller->set_gen_top_indicator( $method ); - $scroller->set_gen_bottom_indicator( $method ) + $scroller->set_gen_bottom_indicator( $method ); Accessors for the generators for the top and bottom indicator text. If set, each should be a CODE reference or method name on the scroller which will be @@ -960,7 +963,7 @@ if defined and non-empty, will be displayed in an indicator window. This will be a small one-line window displayed at the top right or bottom right corner of the Scroller's window. - $text = $scroller->$method() + $text = $scroller->$method(); The ability to pass method names allows subclasses to easily implement custom logic as methods without having to capture a closure. @@ -983,7 +986,7 @@ method set_gen_bottom_indicator =head2 update_indicators - $scroller->update_indicators + $scroller->update_indicators; Calls any defined generators for indicator text, and updates the indicator windows with the returned text. This may be useful if the functions would diff --git a/lib/Tickit/Widget/Scroller/Item/RichText.pm b/lib/Tickit/Widget/Scroller/Item/RichText.pm index c101041..e5fe349 100644 --- a/lib/Tickit/Widget/Scroller/Item/RichText.pm +++ b/lib/Tickit/Widget/Scroller/Item/RichText.pm @@ -1,13 +1,13 @@ # You may distribute under the terms of either the GNU General Public License # or the Artistic License (the same terms as Perl itself) # -# (C) Paul Evans, 2011-2021 -- leonerd@leonerd.org.uk +# (C) Paul Evans, 2011-2023 -- leonerd@leonerd.org.uk use v5.26; use warnings; -use Object::Pad 0.57; +use Object::Pad 0.800; -package Tickit::Widget::Scroller::Item::RichText 0.31; +package Tickit::Widget::Scroller::Item::RichText 0.32; class Tickit::Widget::Scroller::Item::RichText :strict(params) :isa(Tickit::Widget::Scroller::Item::Text); @@ -89,6 +89,16 @@ sub new_from_formatting ( $class, $str, %opts ) ); } +my %PENCACHE; +method pen_for_tags ( $tags ) +{ + # Cache the pens + my $key = join "|", map { "$_=" . ( $tags->{$_} // "" ) } sort keys %$tags; + + # Don't worry if extra tags left over, they just aren't rendering attributes + return $PENCACHE{$key} //= Tickit::Pen::Immutable->new_from_attrs( $tags ); +} + method _build_chunks_for ( $str ) { my @chunks; @@ -96,8 +106,7 @@ method _build_chunks_for ( $str ) $str->iter_substr_nooverlap( sub { my ( $substr, %tags ) = @_; - my $pen = Tickit::Pen->new_from_attrs( \%tags ); - # Don't worry if extra tags left over, they just aren't rendering attributes + my $pen = $self->pen_for_tags( \%tags ); my @lines = split m/\n/, $substr, -1 or return; my $lastline = pop @lines; push @chunks, [ $_, textwidth( $_ ), pen => $pen, linebreak => 1 ] for @lines; diff --git a/lib/Tickit/Widget/Scroller/Item/Text.pm b/lib/Tickit/Widget/Scroller/Item/Text.pm index 8a514cd..acf0e01 100644 --- a/lib/Tickit/Widget/Scroller/Item/Text.pm +++ b/lib/Tickit/Widget/Scroller/Item/Text.pm @@ -5,9 +5,9 @@ use v5.26; use warnings; -use Object::Pad 0.70 ':experimental(adjust_params)'; +use Object::Pad 0.800 ':experimental(adjust_params)'; -package Tickit::Widget::Scroller::Item::Text 0.31; +package Tickit::Widget::Scroller::Item::Text 0.32; class Tickit::Widget::Scroller::Item::Text :strict(params); @@ -42,7 +42,7 @@ the C regexp pattern). =head2 new - $item = Tickit::Widget::Scroller::Item::Text->new( $text, %opts ) + $item = Tickit::Widget::Scroller::Item::Text->new( $text, %opts ); Constructs a new text item, containing the given string of text. Once constructed, the item is immutable. @@ -112,7 +112,7 @@ ADJUST :params ( =head2 chunks - @chunks = $item->chunks + @chunks = $item->chunks; Returns the chunks of text displayed by this item. Each chunk is represented by an ARRAY reference of three fields, giving the text string, its width in @@ -166,23 +166,23 @@ method height_for_width ( $width ) my ( $text, $textwidth, %opts ) = @$chunk; if( $textwidth <= $line_remaining ) { - push @$thisline, [ $text, $textwidth, $opts{pen} ]; + push @$thisline, [ $text =~ s/\xA0/ /gr, $textwidth, $opts{pen} ]; $line_remaining -= $textwidth; } else { # Split this chunk at most $line_remaining chars my $eol_ch = cols2chars $text, $line_remaining; - if( $eol_ch < length $text && substr( $text, $eol_ch, 1 ) =~ m/\S/ ) { + if( $eol_ch < length $text && substr( $text, $eol_ch, 1 ) =~ m/[\S\xA0]/ ) { # TODO: This surely must be possible without substr()ing a temporary - if( substr( $text, 0, $eol_ch ) =~ m/\S+$/ and + if( substr( $text, 0, $eol_ch ) =~ m/[\S\xA0]+$/ and ( $-[0] > 0 or @$thisline ) ) { $eol_ch = $-[0]; } } my $partial_text = substr( $text, 0, $eol_ch ); - my $partial_chunk = [ $partial_text, textwidth( $partial_text ), $opts{pen} ]; + my $partial_chunk = [ $partial_text =~ s/\xA0/ /gr, textwidth( $partial_text ), $opts{pen} ]; push @$thisline, $partial_chunk; my $bol_ch = pos $text = $eol_ch; diff --git a/t/01item-text.t b/t/01item-text.t index 900c8db..ad9ebd1 100644 --- a/t/01item-text.t +++ b/t/01item-text.t @@ -2,6 +2,7 @@ use v5.26; use warnings; +use utf8; use Test2::V0; @@ -174,8 +175,6 @@ drain_termlog; # Odd Unicode { - use utf8; - $term->clear; drain_termlog; @@ -203,6 +202,37 @@ drain_termlog; 'Display for render with Unicode' ); } +# Non-breaking spaces +{ + $term->clear; + drain_termlog; + + my $item = Tickit::Widget::Scroller::Item::Text->new( "abcdef 12\x{A0}34" ); + + is( $item->height_for_width( 11 ), 2, 'height_for_width 2 with NBSP' ); + + $item->render( $rb, top => 0, firstline => 0, lastline => 1, width => 11, height => 2 ); + $rb->flush_to_term( $term ); + + flush_tickit; + + is_termlog( [ GOTO(0,0), + SETPEN, + PRINT("abcdef "), + SETPEN, + ERASECH(4), + GOTO(1,0), + SETPEN, + PRINT("12 34"), + SETPEN, + ERASECH(6) ], + 'Termlog for render with NBSP' ); + + is_display( [ [TEXT("abcdef")], + [TEXT("12 34")] ], + 'Display for render with NBSP' ); +} + # Empty { $term->clear; diff --git a/t/02item-richtext.t b/t/02item-richtext.t index a1a8ffd..0e379cf 100644 --- a/t/02item-richtext.t +++ b/t/02item-richtext.t @@ -25,10 +25,10 @@ isa_ok( $item, [ "Tickit::Widget::Scroller::Item::Text" ], '$item' ); is( [ $item->chunks ], # Stringify the pens so Test2 will compare the stringified versions - [ [ "My ", 3, pen => "".Tickit::Pen->new() ], - [ "message", 7, pen => "".Tickit::Pen->new( b => 1 ) ], - [ " ", 1, pen => "".Tickit::Pen->new() ], - [ "here", 4, pen => "".Tickit::Pen->new( u => 1 ) ] ], + [ [ "My ", 3, pen => "".Tickit::Pen::Immutable->new() ], + [ "message", 7, pen => "".Tickit::Pen::Immutable->new( b => 1 ) ], + [ " ", 1, pen => "".Tickit::Pen::Immutable->new() ], + [ "here", 4, pen => "".Tickit::Pen::Immutable->new( u => 1 ) ] ], '$item->chunks' ); is( $item->height_for_width( 80 ), 1, 'height_for_width 80' ); @@ -65,10 +65,10 @@ is_display( [ [TEXT("My "), TEXT("message",b=>1), BLANK(1), TEXT("here",u=>1)] ] my $item = Tickit::Widget::Scroller::Item::RichText->new( $str ); is( [ $item->chunks ], - [ [ "Another ", 8, pen => "".Tickit::Pen->new() ], - [ "message", 7, pen => "".Tickit::Pen->new( b => 1 ), linebreak => 1 ], - [ "with", 4, pen => "".Tickit::Pen->new( b => 1 ) ], - [ " linefeeds", 10, pen => "".Tickit::Pen->new() ] ], + [ [ "Another ", 8, pen => "".Tickit::Pen::Immutable->new() ], + [ "message", 7, pen => "".Tickit::Pen::Immutable->new( b => 1 ), linebreak => 1 ], + [ "with", 4, pen => "".Tickit::Pen::Immutable->new( b => 1 ) ], + [ " linefeeds", 10, pen => "".Tickit::Pen::Immutable->new() ] ], '$item->chunks with linefeeds' ); } diff --git a/t/10initial.t b/t/10initial.t index be1d567..fdce30a 100644 --- a/t/10initial.t +++ b/t/10initial.t @@ -17,7 +17,7 @@ my $scroller = Tickit::Widget::Scroller->new; ok( defined $scroller, 'defined $scroller' ); $scroller->push( - map { Tickit::Widget::Scroller::Item::Text->new( $_ ) } + my @items = map { Tickit::Widget::Scroller::Item::Text->new( $_ ) } "The first line", "Another line in the middle", "The third line", @@ -64,6 +64,10 @@ is( $scroller->item2line( 0, -1 ), 0, 'item2line 0, -1' ); is( $scroller->item2line( 1 ), 1, 'item2line 1' ); is( $scroller->item2line( 2 ), 2, 'item2line 2' ); +is( $scroller->item2line( $items[0] ), 0, 'item2line $items[0]' ); +is( $scroller->item2line( $items[1] ), 1, 'item2line $items[1]' ); +is( $scroller->item2line( $items[2] ), 2, 'item2line $items[2]' ); + is( $scroller->item2line( -1 ), 2, 'item2line -1' ); resize_term( 25, 20 ); -- cgit v1.2.3