2014-06-06 33 views
3

我使用Curses :: UI :: Grid來顯示錶格數據。該窗口由一個表和幾個按鈕來導航數據顯示窗口到其他窗口的如下圖所示: Curses::UI::Grid tabular data sampleCurses :: UI :: Grid標籤捕獲

然而,所顯示的數據時,焦點轉到第一行和,如果我使用的標籤將焦點轉移到下一個UI控件,它永遠不會進入底部的按鈕。它只是通過第一行的單元循環。

下面是重現該問題的代碼:

#!/usr/bin/env perl 

use strict; 
use warnings; 
use Curses::UI; 
use Curses::UI::Grid; 

my $debug = 0; 

# Create the root object. 
my $cui = new Curses::UI ( 
    -color_support => 1, 
    -clear_on_exit => 1, 
    -debug => $debug, 
); 

create_promote_deps_window(); 
$cui->set_binding(\&exit_dialog , "\cQ"); 

$cui->mainloop(); 

sub exit_dialog { 
    my $return = $cui->dialog(
     -message => "Do you really want to quit?", 
     -title  => "Confirm", 
     -buttons => ['yes', 'no'], 
    ); 

    exit(0) if $return; 
} 

sub create_base_window { 
    my ($name) = @_; 

    $cui->add(
     $name, 
     'Window', 
     -border  => 1, 
     -titlereverse => 0, 
     -padtop  => 2, 
     -padbottom => 3, 
     -ipad   => 1, 
     -title  => 'CTRL-Q to quiz', 
    ); 
} 

sub create_promote_deps_window { 
    my ($name) = @_; 

    my $win = create_base_window($name); 

    my $grid = $win->add(
     'grid', 
     'Grid', 
     -height  => 14, 
     -width  => -1, 
     -editable  => 0, 
     -border  => 1, 
     -process_bindings => { 
      CUI_TAB => undef, 
     }, 
     # -bg  => "blue", 
     # -fg  => "white", 
    ); 

    $grid->add_cell(
     "otp", 
     -width => 10, 
     -label => "OTP" 
    ); 

    $grid->add_cell(
     "commit1", 
     -width => 10, 
     -label => "Commit#" 
    ); 

    $grid->add_cell(
     "otnp", 
     -width => 10, 
     -label => "OTNP" 
    ); 

    $grid->add_cell(
     "commit2", 
     -width => 10, 
     -label => "Commit#" 
    ); 

    $grid->add_cell(
     "overlap", 
     -width => 32, 
     -label => "Overlap" 
    ); 

    my $button_callback = sub { 
     my $this = shift; 

     my $btn_name = $this->get(); 
     if ($btn_name eq "Back") { 
      # give up promotion and return to promote window 
      $win->focus(); 
     } 
     elsif ($btn_name eq "PromoteWithDeps") { 
     } 
    }; 
    $win->add(
     undef, 
     'Buttonbox', 
     -y  => -1, 
     -buttons => [ 
      { 
       -label => "<Back>", 
       -value => "Back", 
       -onpress => $button_callback, 
      }, 
      { 
       -label => "< Promote w/ all deps >", 
       -value => "PromoteWithDeps", 
       -onpress => $button_callback, 
      }, 
     ], 
    ); 

    my @data = (
     ['HDT-10', 'e3042b0', 'HDT-7', '6741e47', 'src/tc/b.p'], 
     ['HDT-10', 'e3042b0', 'HDT-7', '6741e47', 'src/tc/a.p'], 
     ['HDT-10', 'e3042b0', 'HDT-7', '6741e47', 'src/tc/c.p'], 
     ['HDT-10', 'e3042b0', 'HDT-7', '66a3254', 'src/tc/c.p'], 
     ['HDT-10', 'e3042b0', 'HDT-7', '66a3254', 'src/tc/b.p'], 
     ['HDT-10', 'e3042b0', 'HDT-7', '66a3254', 'src/tc/a.p'], 
     ['HDT-10', 'e3042b0', 'HDT-8', '8b65677', 'src/tc/e.p'], 
     ['HDT-10', 'e3042b0', 'HDT-8', '8b65677', 'src/tc/d.p'], 
     ['HDT-10', 'e3042b0', 'HDT-9', '3eefa90', 'src/tc/f.p'], 
    ); 
    foreach my $f (@data) { 

     $grid->add_row(
      undef, 
      # -fg => 'black', 
      # -bg => 'yellow', 
      -cells => { 
       otp  => $f->[0], 
       commit1 => $f->[1], 
       otnp => $f->[2], 
       commit2 => $f->[3], 
       overlap => $f->[4], 
      } 
     ); 
    } 

    $grid->layout(); 
    return $win; 
} 

我如何可以自定義選項卡順序,使用戶可以在按鍵轉移焦點的詛咒:: UI ::以下電網?

謝謝!

回答

1

您遇到的退出網格的困難不在於窗口的標籤排序,而在於Curses :: UI :: Grid爲Tab和Shift + Tab提供了自己的綁定。一個基本的解決方案是提供自己的處理程序時,當電網具有焦點按下Tab鍵和Shift + Tab鍵爲:

sub move_focus { 
    my $widget = $_[0]; 
    my $key = $_[1]; 

    if ($key eq "\t") { 
     $widget->parent()->focus_next(); 
    } 
    else { 
     $widget->parent()->focus_prev(); 
    } 
} 

您可以在此處理程序,然後綁定到你的網格:

$grid->set_binding(\&move_focus, "\t"); 
$grid->set_binding(\&move_focus, KEY_BTAB()); 

然而,您可能會發現使用光標鍵在單元格之間移動非常乏味,因此您可能仍然希望能夠在單元格之間進行切換,並且只在光標位於行尾時跳轉到按鈕。在這種情況下,您的自定義處理程序將需要更加智能一點:

sub move_focus { 
    my $grid = $_[0]; 
    my $key = $_[1]; 

    if ($key eq "\t") { 
     my $last_cell = $grid->get_cell($grid->{_cells}[$#{$grid->{_cells}}]); 
     if ($grid->get_foused_cell() == $last_cell) { 
      $grid->parent()->focus_next(); 
     } 
     else { 
      $grid->next_cell(); 
     } 
    } 
    else { 
     my $first_cell = $grid->get_cell($grid->{_cells}[0]); 
     if ($grid->get_foused_cell() == $first_cell) { 
      $grid->parent()->focus_prev(); 
     } 
     else { 
      $grid->prev_cell(); 
     } 
    } 
}