Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

A Tk callback problem

by dimmesdale (Friar)
on Jul 07, 2002 at 17:38 UTC ( [id://179998]=perlquestion: print w/replies, xml ) Need Help??

dimmesdale has asked for the wisdom of the Perl Monks concerning the following question:

(For more information on the idea of the code, see a node entitled: PerlSol (Solitare in Perl); also, for a complete listing of the code, check out my scratchpad -- I'll try to keep it updated with my changes every so often).

Okay, to the inevitable problem. I've been tinkering with a callback to be invoked when a user clicks on the deck. For now I plan to have three cards (or as many as are available) be moved to the waste. When the cards in the deck are out a rectangle will replace the image that was there to indicate the condition. Clicking the rectangle will take all the cards in the waste (in reverse order) and put them into the deck, dealing three to the waste at the same time. The process will then start again.

Well, after countless errors, fixing things that were 'just slightly wrong' (and the more slightly wrong ones too :), I don't know how to fix the mess I'm in now. I've been tracking where I go in my code, and I've narrowed down the problem (mostly) to this section in the dk_clk procedure:

if($_[1]->num_cards() <= 0) { # deck out of cards $_[0]->delete($_[4]); # Delete card back photo $_[0]->delete($_[3]); # Delete card back image $_[3] = ($_[0])->createRectangle(15,72,84,165); $deleted = 1; $_[1]->take_from($_[2]); $_[2] = Pile->new({ max => 52 }); ($_[0])->bind($_[3], "<Button-1>", [\&dk_clk, $_[1], $_[2], $_[3], $_[4]]); }

After one clicks on the deck until it is empty, this part is invoked. And from there the bind ceases -- so I rebound, but to no avail. If you wish to try it out, you can get the card images here: http://www.jfitz.com/cards/ (downloadable as gif or png in compressed format). As I said, the complete code is at my scratchpad, and here's the subs that are invoked upon a click of the deck:

(A lot of what I have is workaround, just trying to get it to work; suggestions to improve this are welcome, and a fuller 'restoration' project will go on once I have something that does what I want it to do)

$canvas->bind($dk_img, "<Button-1>", [\&frst_clk, $deck, $waste, $dk_img, $back]); my $wst_imgs = []; my $wst_crds = []; sub frst_clk { my $i = 0; my $min = min(2,$_[1]->num_cards()); $wst_crds = []; for (0..$min) { $wst_crds->[$_] = $_[1]->remove_card; } my $c; for(0..$min) { ($wst_crds->[$_])->where($_[2]); ($wst_crds->[$_])->state('up'); $c = ($wst_crds->[$_])->label(); my $path = "$card_dir\\$c.$ext"; my $p = ($_[0])->Photo( -file => $path, -format => 'gif', ); push @$wst_imgs, ($_[0])->createImage(126+15*$i++,118, -image => $ +p); } $_[2]->fill_pile($wst_crds); ($_[0])->bind($_[3], "<Button-1>", [\&dk_clk, $_[1], $_[2], $_[3], $ +_[4]]); } my $deleted = 0; sub dk_clk { my $i = 0; if($deleted) { $_[0]->delete($_[4]); # Delete card back photo $_[0]->delete($_[3]); # Delete card back image # Recreate them with desired properties $_[4] = ($_[0])->Photo(-file => "$card_dir\\b1fv.$ext", -format => 'gif'); $_[3] = ($_[0])->createImage(50,120, -image => $_[4]); $deleted = 0; for(@$wst_imgs) { $_[0]->delete($_); } $wst_imgs = []; ($_[0])->bind($_[3], "<Button-1>", [\&dk_clk, $_[1], $_[2], $_[3], $_[4]]); } for(@$wst_imgs) { $_[0]->coords($_, 126,118); } $wst_crds = []; $wst_imgs = []; my $min = min(2,$_[1]->num_cards()); for (0..$min) { $wst_crds->[$_] = $_[1]->remove_card; } my $c; for(0..$min) { last && print 'Whoa!' unless $wst_crds->[$_]; ($wst_crds->[$_])->where($_[2]); ($wst_crds->[$_])->state('up'); $c = ($wst_crds->[$_])->label(); # (($wst_crds->[$_])->[0])->where($_[2]); # (($wst_crds->[$_])->[0])->state('up'); # $c = (($wst_crds->[$_])->[0])->label(); my $path = "$card_dir\\$c.$ext"; my $p = ($_[0])->Photo( -file => $path, -format => 'gif', ); push @$wst_imgs, ($_[0])->createImage(126+15*$i++,118, -image => $ +p); } $_[2]->fill_pile($wst_crds); if($_[1]->num_cards() <= 0) { # deck out of cards $_[0]->delete($_[4]); # Delete card back photo $_[0]->delete($_[3]); # Delete card back image $_[3] = ($_[0])->createRectangle(15,72,84,165); $deleted = 1; $_[1]->take_from($_[2]); $_[2] = Pile->new({ max => 52 }); ($_[0])->bind($_[3], "<Button-1>", [\&dk_clk, $_[1], $_[2], $_[3], $_[4]]); } # do some drag/drop stuff here once know-how obtained :) } sub min { $_[0] < $_[1] ? $_[0] : $_[1]; }

edited: Sun Jul 7 20:19:41 2002 by jeffa - added readmore tag

Replies are listed 'Best First'.
Re: A Tk callback problem
by stefp (Vicar) on Jul 07, 2002 at 19:35 UTC
    You should improve style if you want someone to go over your code.

    In long subroutines, name your formal parameters by using my ($nm1, $nm2) = @_ to avoid dealing explicitely with @_ within the subroutine. Best code is self-commenting code by savvy use of variables names.

    Incidentally, another possible style is to name actual parameters as well. This is especially interesting if some actual parameters may be missing
    sub add ( nm1 => $val1, $nm2 => $val1 } sub add { local %_ = ( @_ ); $_{nm1} + $_{nm2} }
    If you follow my first advice, this one will be unecessary in this particular case. But here it is anyway, you should use slices:

    [\&db_clk, $_[1], $_[2], $_[3], $_[4] ]
    could be rewritten
    [ \&db_clk, @_[1..4] ]
    .

    -- stefp -- check out TeXmacs wiki

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://179998]
Approved by cjf
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2024-04-19 13:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found