Home > Archive > PerlTk > August 2004 > menu post, Ev subroutine - cross-platfrom compatability problem
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
menu post, Ev subroutine - cross-platfrom compatability problem
|
|
|
| I want to be able to right-click in a text widget, display a custom
right-click menu, and convert the right-click location into a text index. I
have some code that works well on windows, but fails on RedHat (see below).
The problems seem to be the following:
passing Ev('x'), Ev('y') to post() seems to be required for the
$Tk::event->x in the DelLine subroutine. However, using
$menu_r2->post( Ev('x'), Ev('y') );
on a Linux computer (RedHat) results in the menu being posted at the bottom
right of the screen, and i can't get the correct text index either. But the
following post seems to post the menu correctly on Linux:
$menu_r2->post();
but then this breaks the $Tk::event->x call in DelLine subroutine, resulting
in the wrong translation to a text index
Any comments greatfully received!
Nathan
---- CODE ----
# define custom menu and items
my $menu1 = $text_widget->Menu(-tearoff => 0);
$menu1->add('command', -label => 'Delete Line', -command => [\&DelLine,
$text_widget, $menu1 ]);
$text_widget->menu($menu1); # put menu to
use
$text_widget->bind("<Button-3>" => sub { $menu_r2->post( Ev('x'),
Ev('y') ) }); # right-click binding
sub DelLine {
my ($widget, $menu) = @_;
my $x = $Tk::event->x;
my $y = $Tk::event->y;
my $txt_index = $widget_1->index('@'.$x.','.$y); #
translate pointer position to text index
my ($line, $char) = ($txt_index =~ /^(.+?)\.(.+?)$/);
print "text index: ", $txt_index, "\n";
my $nextline = $line + 1;
$widget_1->delete($line.'.0', $nextline.'.0');
$menu->Unpost; # required for windows
}
| |
| Slaven Rezic 2004-08-17, 8:57 pm |
| "Nath" <DON'T_SEND_ME@TRIPE_TO_MY_IN.BOX> writes:
> I want to be able to right-click in a text widget, display a custom
> right-click menu, and convert the right-click location into a text index. I
> have some code that works well on windows, but fails on RedHat (see below).
>
> The problems seem to be the following:
> passing Ev('x'), Ev('y') to post() seems to be required for the
> $Tk::event->x in the DelLine subroutine. However, using
> $menu_r2->post( Ev('x'), Ev('y') );
> on a Linux computer (RedHat) results in the menu being posted at the bottom
> right of the screen, and i can't get the correct text index either. But the
> following post seems to post the menu correctly on Linux:
> $menu_r2->post();
> but then this breaks the $Tk::event->x call in DelLine subroutine, resulting
> in the wrong translation to a text index
>
> Any comments greatfully received!
> Nathan
>
Here's a working version:
use Tk;
$top = new MainWindow;
$text_widget = $top->Text->pack;
$text_widget->insert("end", scalar `cat $ENV{HOME}/.cshrc`);
my $menu1 = $text_widget->Menu(-tearoff => 0);
$menu1->add('command', -label => 'Delete Line',
-command => [\&DelLine, $text_widget, $menu1 ]);
$text_widget->menu($menu1);
sub DelLine {
my ($widget, $menu) = @_;
my $x = $menu->rootx - $text_widget->rootx;
my $y = $menu->rooty - $text_widget->rooty;
my $txt_index = $text_widget->index('@'.$x.','.$y);
warn $txt_index;
my ($line, $char) = ($txt_index =~ /^(.+?)\.(.+?)$/);
print "text index: ", $txt_index, "\n";
my $nextline = $line + 1;
$text_widget->delete($line.'.0', $nextline.'.0');
$menu->Unpost;
}
MainLoop;
__END__
Some comments on the code:
* You only need to set the menu with menu() method, binding with <3>
is not necessary (but maybe I misinterpreted your code because of
bad wrapping --- please make sure to tell your newsreader to not
wrap posts with code in it!)
* It's probably easiest to use the difference of the absolute
positions of text widget and menu (the rootx/rooty positions).
* And it's always easier to hack on someone's code if it contains
minimal *running* code.
Regards,
Slaven
--
Slaven Rezic - slaven <at> rezic <dot> de
Tk-AppMaster: a perl/Tk module launcher designed for handhelds
http://tk-appmaster.sf.net
| |
|
|
"Slaven Rezic" <slaven@rezic.de> wrote in message news:87r7q5o58q.fsf@vran.herceg.de...
> "Nath" <DON'T_SEND_ME@TRIPE_TO_MY_IN.BOX> writes:
>
>
> Here's a working version:
>
> use Tk;
>
> $top = new MainWindow;
>
> $text_widget = $top->Text->pack;
> $text_widget->insert("end", scalar `cat $ENV{HOME}/.cshrc`);
>
> my $menu1 = $text_widget->Menu(-tearoff => 0);
> $menu1->add('command', -label => 'Delete Line',
> -command => [\&DelLine, $text_widget, $menu1 ]);
>
> $text_widget->menu($menu1);
>
> sub DelLine {
> my ($widget, $menu) = @_;
>
> my $x = $menu->rootx - $text_widget->rootx;
> my $y = $menu->rooty - $text_widget->rooty;
>
> my $txt_index = $text_widget->index('@'.$x.','.$y);
> warn $txt_index;
> my ($line, $char) = ($txt_index =~ /^(.+?)\.(.+?)$/);
>
> print "text index: ", $txt_index, "\n";
> my $nextline = $line + 1;
> $text_widget->delete($line.'.0', $nextline.'.0');
>
> $menu->Unpost;
> }
>
>
>
> MainLoop;
>
> __END__
>
> Some comments on the code:
>
> * You only need to set the menu with menu() method, binding with <3>
> is not necessary (but maybe I misinterpreted your code because of
> bad wrapping --- please make sure to tell your newsreader to not
> wrap posts with code in it!)
>
> * It's probably easiest to use the difference of the absolute
> positions of text widget and menu (the rootx/rooty positions).
>
> * And it's always easier to hack on someone's code if it contains
> minimal *running* code.
>
> Regards,
> Slaven
>
> --
> Slaven Rezic - slaven <at> rezic <dot> de
>
> Tk-AppMaster: a perl/Tk module launcher designed for handhelds
> http://tk-appmaster.sf.net
Thanks for your post, i'm working through it as i type!
One other question: If i wanted to create a menu that was accessable to several text widgets, how would i do this?
because does the following command:
my $menu1 = $text_widget->Menu(-tearoff => 0);
mean $menu1 is only accessable via $text_widget or can i also use:
$other_text_widget->menu($menu1);
Thanks for your help!
Nathan
p.s. my newsreader won't turn off wrapping, so i've set it to the max no of chars - time to move away from outlook express to
netscape me thinks!
| |
|
| Slaven Rezic wrote:
> "Nath" <DON'T_SEND_ME@TRIPE_TO_MY_IN.BOX> writes:
>
>
>
>
> Here's a working version:
>
> use Tk;
>
> $top = new MainWindow;
>
> $text_widget = $top->Text->pack;
> $text_widget->insert("end", scalar `cat $ENV{HOME}/.cshrc`);
>
> my $menu1 = $text_widget->Menu(-tearoff => 0);
> $menu1->add('command', -label => 'Delete Line',
> -command => [\&DelLine, $text_widget, $menu1 ]);
>
> $text_widget->menu($menu1);
>
> sub DelLine {
> my ($widget, $menu) = @_;
>
> my $x = $menu->rootx - $text_widget->rootx;
> my $y = $menu->rooty - $text_widget->rooty;
>
> my $txt_index = $text_widget->index('@'.$x.','.$y);
> warn $txt_index;
> my ($line, $char) = ($txt_index =~ /^(.+?)\.(.+?)$/);
>
> print "text index: ", $txt_index, "\n";
> my $nextline = $line + 1;
> $text_widget->delete($line.'.0', $nextline.'.0');
>
> $menu->Unpost;
> }
>
>
>
> MainLoop;
>
> __END__
>
> Some comments on the code:
>
> * You only need to set the menu with menu() method, binding with <3>
> is not necessary (but maybe I misinterpreted your code because of
> bad wrapping --- please make sure to tell your newsreader to not
> wrap posts with code in it!)
>
> * It's probably easiest to use the difference of the absolute
> positions of text widget and menu (the rootx/rooty positions).
>
> * And it's always easier to hack on someone's code if it contains
> minimal *running* code.
>
> Regards,
> Slaven
>
I've tested the code, and it works correctly on Linux, however it
doesn't work on Windows:
$menu->rootx and $menu->rooty do not return the position of the menu!
any ideas why this is and whether there may be a more universal approach
to doing this before i start writing blocks for differnt OS's?
Thanks
Nathan
| |
| Slaven Rezic 2004-08-18, 8:57 pm |
| "Nath" <DON'T_SEND_ME@TRIPE_TO_MY_IN.BOX> writes:
> "Slaven Rezic" <slaven@rezic.de> wrote in message news:87r7q5o58q.fsf@vran.herceg.de...
>
> Thanks for your post, i'm working through it as i type!
>
> One other question: If i wanted to create a menu that was accessable to several text widgets, how would i do this?
> because does the following command:
> my $menu1 = $text_widget->Menu(-tearoff => 0);
> mean $menu1 is only accessable via $text_widget or can i also use:
> $other_text_widget->menu($menu1);
>
I don't think you can really *share* a menu widget across multiple
widgets. But of course you can share a subroutine which creates a menu
across multiple widgets. Maybe you can even create a subclass of
Tk::Text.
Regards,
Slaven
--
Slaven Rezic - slaven <at> rezic <dot> de
Dump a Tk canvas as an xfig file:
http://search.cpan.org/search?mode=...y=Tk::CanvasFig
| |
| Slaven Rezic 2004-08-18, 8:57 pm |
| Nath <DON'T_SEND_ME@TRIPE_TO_MY_IN.BOX> writes:
> Slaven Rezic wrote:
>
> I've tested the code, and it works correctly on Linux, however it
> doesn't work on Windows:
> $menu->rootx and $menu->rooty do not return the position of the menu!
> any ideas why this is and whether there may be a more universal
> approach to doing this before i start writing blocks for differnt OS's?
My guess is that on Windows native menu are used, for which Tk maybe
does not get enough geometry information. Maybe you can try
$menu->geometry as an alternative?
Regards,
Slaven
--
Slaven Rezic - slaven <at> rezic <dot> de
sf-upload: make batch releases on SourceForge
http://sf-upload.sf.net
|
|
|
|
|