Skip Menu |

This queue is for tickets about the Curses-UI CPAN distribution.

Report information
The Basics
Id: 7027
Status: resolved
Priority: 0/
Queue: Curses-UI

People
Owner: Nobody in particular
Requestors: wbarsse [...] pfn.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.93
Fixed in: (no value)



Subject: -releasefocus behavior in Curses::UI::Container
Hi, Though this is a bug report, let me first say how great I find Curses::UI ! Now for the nitty-gritty, - Curses::UI v 0.92, 0.93 - perl v 5.8.3 - uname Linux 2.4.22 i686 unknown When using a Container with "-releasefocus" set, the following two (related) problems can be observed : - tabbing over the last _enabled_ component will not result in leaving the container if that component is followed by a non focusable component in the focusorder. This is due to the logic in focus_next that relies solely on the current component's position with respect to focusorder, ie it would maybe be necessary to replace the ++$idx logic with a loop awaiting the first focusable component (with full loop detection). - same problem (inverted) when using focus_previous Cheers, - William Barsse
From: wbarsse [...] pfn.com
Oh, forgot to add the patch which seems to address the problem ... Sorry, for the double post. - William
--- lib/Curses/UI/Container.pm.orig 2004-07-20 12:05:52.000000000 -0400 +++ lib/Curses/UI/Container.pm 2004-07-20 12:17:29.000000000 -0400 @@ -276,16 +276,22 @@ my $circle_flag = 0; # Go to the previous object or wraparound. - if ( --$idx < 0) { - $idx = @{$this->{-focusorder}} - 1; - $circle_flag = 1; + for (my $wrap_idx = $idx ;;) { + $idx--; + if ($idx < 0) { + $idx = @{$this->{-focusorder}} - 1; + $circle_flag = 1; + } + my $new_obj = $this->getobj($this->{-focusorder}[$idx]); + last if ((defined $new_obj && $new_obj->focusable) || + ($wrap_idx == $idx)); } # Focus the previous object. - $this->focus($this->{-focusorder}->[$idx], undef, -1); - if ( $circle_flag && $this->{-releasefocus} ) { $this->{-parent}->focus_prev; + } else { + $this->focus($this->{-focusorder}->[$idx], undef, -1); } } @@ -304,16 +310,24 @@ my $idx = $this->focusorder_id2idx($id); # Go to the next object or wraparound. - if ( ++$idx > (@{$this->{-focusorder}}-1) ) { - $idx = 0; + my $circle_flag = 0; + for (my $wrap_idx = $idx ;;) { + $idx++; + if ($idx >= scalar (@{$this->{-focusorder}}) ) { + $idx = 0; + $circle_flag = 1; + } + my $new_obj = $this->getobj($this->{-focusorder}[$idx]); + last if ((defined $new_obj && $new_obj->focusable) || + ($wrap_idx == $idx)); } - + # Focus the next object. - $this->focus($this->{-focusorder}->[$idx], undef, +1); - #check if we have to release the focus - if ( $idx == 0 && $this->{-releasefocus} ) { + if ( $circle_flag && $this->{-releasefocus} ) { $this->{-parent}->focus_next; + } else { + $this->focus($this->{-focusorder}->[$idx], undef, +1); } }
Thanks, applied. Marcus
I'm sorry for this late reply, but the patch I previously submitted has two issues (one big, one small) : - when releasing the focus, I removed the previous logic to focus the first component before the final release. This leads to a workable UI, but "feels" very unintuitive - there is one unnecessary check being done ... looks ugly Anyway, here is an updated version ; again forgive my lack thoroughness in the previous patch. - William [MARCUS - Thu Jul 22 08:48:40 2004]: Show quoted text
> Thanks, applied. > Marcus
--- lib/Curses/UI/Container.pm.orig 2004-07-21 09:52:04.000000000 -0400 +++ lib/Curses/UI/Container.pm 2004-07-21 09:54:29.000000000 -0400 @@ -276,14 +276,18 @@ my $circle_flag = 0; # Go to the previous object or wraparound. - if ( --$idx < 0) { - $idx = @{$this->{-focusorder}} - 1; - $circle_flag = 1; + until ($circle_flag) { + $idx--; + if ($idx < 0) { + $idx = @{$this->{-focusorder}} - 1; + $circle_flag = 1; + } + my $new_obj = $this->getobj($this->{-focusorder}[$idx]); + last if (defined $new_obj && $new_obj->focusable); } # Focus the previous object. $this->focus($this->{-focusorder}->[$idx], undef, -1); - if ( $circle_flag && $this->{-releasefocus} ) { $this->{-parent}->focus_prev; } @@ -304,15 +308,21 @@ my $idx = $this->focusorder_id2idx($id); # Go to the next object or wraparound. - if ( ++$idx > (@{$this->{-focusorder}}-1) ) { - $idx = 0; + my $circle_flag = 0; + until ($circle_flag) { + $idx++; + if ($idx >= scalar (@{$this->{-focusorder}}) ) { + $idx = 0; + $circle_flag = 1; + } + my $new_obj = $this->getobj($this->{-focusorder}[$idx]); + last if (defined $new_obj && $new_obj->focusable); } - + # Focus the next object. $this->focus($this->{-focusorder}->[$idx], undef, +1); - #check if we have to release the focus - if ( $idx == 0 && $this->{-releasefocus} ) { + if ( $circle_flag && $this->{-releasefocus} ) { $this->{-parent}->focus_next; } }
Thanks, applied again :-) Marcus