File Coverage

lib/Devel/ebug/Wx/Service/CommandManager.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Devel::ebug::Wx::Service::CommandManager;
2              
3 1     1   704 use strict;
  1         2  
  1         37  
4 1     1   6 use base qw(Devel::ebug::Wx::Service::Base);
  1         1  
  1         99  
5 1     1   5 use Devel::ebug::Wx::Plugin qw(:manager :plugin);
  1         2  
  1         180  
6              
7             load_plugins( search_path => 'Devel::ebug::Wx::Command' );
8              
9             __PACKAGE__->mk_accessors( qw(wxebug key_map _menu_tree) );
10              
11 1     1   457 use Wx qw(:menu);
  0            
  0            
12             use Wx::Event qw(EVT_MENU EVT_UPDATE_UI);
13              
14             sub service_name : Service { 'command_manager' }
15              
16             sub initialize {
17             my( $self, $manager ) = @_;
18              
19             $self->{wxebug} = $manager->get_service( 'ebug_wx' );
20             ( $self->{key_map}, $self->{_menu_tree} ) = $self->_setup_commands;
21             }
22              
23             sub get_menu_bar {
24             my( $self ) = @_;
25              
26             return $self->_build_menu( $self->_menu_tree );
27             }
28              
29             sub _build_menu {
30             my( $self, $menu_tree ) = @_;
31              
32             my $mbar = Wx::MenuBar->new;
33              
34             foreach my $rv ( sort { $a->{priority} <=> $b->{priority} }
35             values %$menu_tree ) {
36             my $menu = Wx::Menu->new;
37             my $prev_pri = 0;
38             foreach my $item ( sort { $a->{priority} <=> $b->{priority} }
39             @{$rv->{childs}} ) {
40             if( $prev_pri && $item->{priority} != $prev_pri ) {
41             $menu->AppendSeparator;
42             }
43             my $label = $item->{key} ?
44             sprintf( "%s\t%s", $item->{label}, $item->{key} ) :
45             $item->{label};
46             my $style = $item->{checkable} ? wxITEM_CHECK : wxITEM_NORMAL;
47             my $mitem = $menu->Append( -1, $label, '', $style );
48             EVT_MENU( $self->wxebug, $mitem, $item->{sub} );
49             if( $item->{update_menu} ) {
50             EVT_UPDATE_UI( $self->wxebug, $mitem, $item->{update_menu} );
51             }
52             $prev_pri = $item->{priority};
53             }
54             $mbar->Append( $menu, $rv->{label} );
55             }
56              
57             return $mbar;
58             }
59              
60             sub _setup_commands {
61             my( $self ) = @_;
62             my( %key_map, %menu_tree, %cmds );
63              
64             # passing $wxebug here is correct because a command might
65             # want to act on a single instance
66             # FIXME: duplicates?
67             %cmds = map $_->( $self->wxebug ),
68             Devel::ebug::Wx::Plugin->commands;
69             foreach my $id ( grep $cmds{$_}{key}, keys %cmds ) {
70             $key_map{$cmds{$id}{key}} = $cmds{$id};
71             }
72             foreach my $id ( grep $cmds{$_}{tag}, keys %cmds ) {
73             $menu_tree{$cmds{$id}{tag}} = { childs => [],
74             priority => 0,
75             %{$cmds{$id}},
76             };
77             }
78             foreach my $id ( grep $cmds{$_}{menu}, keys %cmds ) {
79             die "Unknown menu: $cmds{$id}{menu}"
80             unless $menu_tree{$cmds{$id}{menu}};
81             push @{$menu_tree{$cmds{$id}{menu}}{childs}}, { priority => 0,
82             %{$cmds{$id}},
83             };
84             }
85              
86             return ( \%key_map, \%menu_tree );
87             }
88              
89             sub handle_key {
90             my( $self, $code ) = @_;
91             my $char = chr( $code );
92              
93             if( my $cmd = $self->key_map->{$char} ) {
94             $cmd->{sub}->( $self->wxebug );
95             }
96             }
97              
98             1;