Hi,

A small update to previous code. On wxGTK EVT_LIST_ITEM_RIGHT_CLICK events are generated even if a right click in the wxListCtrl is not on an item. Amended attachment handles this.

#########################################################################################
# Description:  wxListCtrl Test
# Created       Mon Feb 04 15:01:53 2013
# svn id        $Id:$
# Copyright:    Copyright (c) 2013 Mark Dootson
# Licence:      This program is free software; you can redistribute it 
#               and/or modify it under the same terms as Perl itself
#########################################################################################

package MainWindow;
use strict;
use warnings;
use Wx qw( :id :misc :window :sizer :panel :listctrl );
use base qw( Wx::Frame );
use Wx::Event qw(
    EVT_LIST_ITEM_SELECTED EVT_LIST_ITEM_DESELECTED
    EVT_LIST_ITEM_ACTIVATED EVT_LIST_ITEM_FOCUSED
    EVT_LIST_ITEM_RIGHT_CLICK 
);


sub new {
    my $class = shift;
    my $self = $class->SUPER::new( @_ );
    
    my $mainpanel = Wx::Panel->new($self, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL|wxBORDER_NONE );
    my $list = Wx::ListCtrl->new($mainpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL  );
    my $mainsizer = Wx::BoxSizer->new(wxVERTICAL);
    my $panelsizer = Wx::BoxSizer->new(wxVERTICAL);
    
    $panelsizer->Add($list,1,wxALL|wxEXPAND, 0);
    $mainpanel->SetSizer($panelsizer);
    $mainsizer->Add($mainpanel,1,wxALL|wxEXPAND, 0);
    $self->SetSizer($mainsizer);
    
    my @data = (
        [qw ( R0CO ROC1 ROC2 ) ],
        [qw ( R1CO R1C1 R1C2 ) ],
        [qw ( R2CO R2C1 R2C2 ) ],
    );
    
    $list->InsertColumn(0, 'Col 0', wxLIST_FORMAT_LEFT, 100);
    $list->InsertColumn(1, 'Col 1', wxLIST_FORMAT_LEFT, 100);
    $list->InsertColumn(2, 'Col 2', wxLIST_FORMAT_LEFT, 100);
    
    for (my $i = 0; $i < @data; $i++) {
        $list->InsertStringItem($i, $data[$i]->[0]);
        $list->SetItem($i, 1, $data[$i]->[1]);
        $list->SetItem($i, 2, $data[$i]->[2]);
    }
    
    EVT_LIST_ITEM_SELECTED($self, $list, \&OnItemSelected);
    EVT_LIST_ITEM_DESELECTED($self, $list, \&OnItemDeselected);
    EVT_LIST_ITEM_ACTIVATED($self, $list, \&OnItemActivated);
    EVT_LIST_ITEM_FOCUSED($self, $list, \&OnItemFocused);
    EVT_LIST_ITEM_RIGHT_CLICK($self, $list, \&OnItemRightClick);
    
    return $self;
}

sub OnItemSelected {
    my($self, $event) = @_;
    $event->Skip(1);
    
    print q(EVT_LIST_ITEM_SELECTED) . qq(\n);
    
}

sub OnItemDeselected {
    my($self, $event) = @_;
    $event->Skip(1);
    
    print q(EVT_LIST_ITEM_DESELECTED) . qq(\n);
}

sub OnItemActivated {
    my($self, $event) = @_;
    $event->Skip(1);
    
    print q(EVT_LIST_ITEM_ACTIVATED) . qq(\n);
}

sub OnItemFocused {
    my($self, $event) = @_;
    $event->Skip(1);
    
    print q(EVT_LIST_ITEM_FOCUSED) . qq(\n);
}

sub OnItemRightClick {
    my($self, $event) = @_;
    $event->Skip(1);
    print q(EVT_LIST_ITEM_RIGHT_CLICK) . qq(\n);
    
    my $listctrl  = $event->GetEventObject;
    my $point = $event->GetPoint();
    
    my ($itemindex, $flags, $subindex) = $listctrl->HitTest($point);
    
    # return if not valid $itemindex;
    return if (!defined($itemindex) || $itemindex == -1 );
    
    if( !Wx::wxMSW() ) {
        # $subindex only populated on wxMSW
        $subindex = $self->_get_generic_subitem( $listctrl, $point );
    }
    
    print qq($itemindex, $flags, $subindex\n);
    my $text = $listctrl->GetItem($itemindex, $subindex)->GetText;
    print qq(Right clicked text: $text\n);
}

sub _get_generic_subitem {
    my($self, $listctrl, $point) = @_;
    
    # iterate through columms and check if $point->x is within that column width
    
    my $left = 0;
    for(my $i = 0; $i < $listctrl->GetColumnCount; $i ++) {
        my $right = $left + $listctrl->GetColumnWidth($i);
        if($point->x >= $left && $point->x <= $right) {
            return $i;
        } else {
            $left = $right + 1;
        }
    }
    
    Wx::LogError('Could not determine column in right click');
    return 0;
}


package Application;
use strict;
use warnings;
use Wx;

use base qw( Wx::App );


sub OnInit {
    my $self = shift;
    
    my $mwin = MainWindow->new(undef, -1, 'Test wxListCtrl' );
    
    $self->SetTopWindow($mwin);
    $mwin->Show(1);
}

package main;

my $app = Application->new;
$app->MainLoop;


1;

Reply via email to