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;