views:

50

answers:

2

For example in the following script:

use Tk;

my $mw = new MainWindow;
my $t  = $mw->Scrolled("Text")->pack;

my $popup = $mw->Menu(
    -menuitems => [
        [
            Button   => 'Copy Selected',
            -state   => "disabled",
            -command => sub {$t->clipboardColumnCopy}
        ],
    ]
);
$t->menu($popup);

MainLoop;

How do I tell when selection happens so that I can use the following code

$popup->entryconfigure(1, -state=>'normal');

to change the menu item state?

UPDATE:

Big thanks to @Chas and @gbacon :)

I think maybe I can also combine the two good answers:

$t->bind(
    "<Button1-ButtonRelease>",
    sub {
        local $@;
        my $state = defined eval { $t->SelectionGet } ? 
            "normal" : "disable";
        $popup->entryconfigure(1, -state => $state)
    }
);
+1  A: 

I don't know Tk very well, but this is an answer (but maybe not the right answer):

#!/usr/bin/perl

use strict;
use warnings;

use Tk;

my $mw = new MainWindow;
my $t  = $mw->Text->pack;


my $popup = $mw->Menu(
    -menuitems => [
        [ Button => 'Copy Selected', -state => "disabled", -command => sub {$t->clipboardColumnCopy} ],
    ]
);
$t->menu($popup);

$t->bind(
    "<Button1-ButtonRelease>",
    sub {
        my $text = $t->getSelected;
        if (length $text) {
            $popup->entryconfigure(1, -state => 'normal');
        } else {
            $popup->entryconfigure(1, -state => 'disabled');
        }
    }
);

MainLoop;
Chas. Owens
@Chas Owens, thanks a lot! I never thought of using the event binding, but this does the trick very well. Thanks :)
Mike
+1  A: 

A few changes produce the behavior you want. The code below watches <ButtonPress-1> which may clear the selection and if so disables Copy Selected. For <ButtonPress-3>, it enables the menu item if a selection is present.

my $copySelectedLabel = "Copy Selected";
my $popup = $mw->Menu(
    -menuitems => [
        [
            Button   => $copySelectedLabel,
            -state   => "disabled",
            -command => sub {$t->clipboardColumnCopy}
        ],
    ]
);

sub maybeEnableCopySelected {
  local $@;
  $popup->entryconfigure($copySelectedLabel, -state => "normal")
    if defined eval { $t->SelectionGet };
}

sub maybeDisableCopySelected {
  local $@;
  $popup->entryconfigure($copySelectedLabel, -state => "disabled")
    unless defined eval { $t->SelectionGet };
}

$t->bind('<ButtonPress-1>' => \&maybeDisableCopySelected);
$t->bind('<ButtonPress-3>' => \&maybeEnableCopySelected);
$t->menu($popup);
Greg Bacon
@gbacon, I see the point of checking if SelectionGet is defined. Thanks a lot! But there's something weird. Even after selecting is done, ButtonPress-3 won't enable Copy Selected immediately. I'll have to move the mouse around a little bit and BUttonPress-3 again to finally activate Copy Selected. I have no idea why this is happening. Or maybe because I'm running ActivePerl on Windows? Thanks anyway :)
Mike
@Mike I tested it on Linux, not Windows, and it behaved correctly. That's a frustrating incompatibility, but it appears you have a solution that works, so go with it!
Greg Bacon