For Programmers: Free Programming Magazines  


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
Nath

2004-08-17, 8:56 am

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
Nath

2004-08-18, 8:56 am


"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!


Nath

2004-08-18, 8:56 am

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
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com