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

I am trying to do a commandline type emulator using a Tk::Text widget and even if I do say so myself, have done much better then I expected. I have however run into a problem, I am trying to represent a sort of old style main frame form which is filled in with data. I can print out the form but I've tried allsorts of ways to place the curser but to no eval.

1. Is this the right widget to do this sort of job?
2. How can I place the curser? The place I need to do this is in startText
3. Is this a pointless task and would an entry box type interface be better?

Remember some of the users have been working on mainframes for years and love the session stlye interface.

use Tk; use strict; my $start ='1.0'; my $mw = new MainWindow(); my $ta = $mw->Text(-bg => 'black', -fg => 'green', -insertbackground=>'green')->pack(); $ta->focus(); $ta->bind('<Return>',[\&getText, \$start]); $ta->bind('<Up>',[\&setStart, \$start]); $ta->bind('<Down>',[\&setStart, \$start]); $ta->bind('<Left>',[\&setStart, \$start]); $ta->bind('<Right>',[\&setStart, \$start]); $ta->bind('<Control-c>',sub{exit}); startText(); MainLoop; sub startText{ insertText("Mainframe Monkey Version \'dev\' Oct 2004 - RJC Pr +oduction\n"); insertText("\n USER: [ ]\n\n PASSWORD:[ + ]"); #need to loop back to the USER input at this point setStart(); } sub setStart{ $start = $ta->index('insert'); } sub getText{ my @lp = split /\./,$start; my $com = $ta->get($start, "$lp[0].end"); chomp $com; $com =~ s/ //g; $com =~ s/_//g; doAction($com); $start = $ta->index('insert'); } sub doAction{ my $com = $_[0]; $com = uc $com; if ($com eq 'EXIT'){$mw->destroy} elsif ($com eq 'DIR'){my $dir = `dir`;insertText($dir);} elsif ($com eq 'CLS'){$ta->delete('1.0','end');setStart();} else {insertText("\nUnKown command or program\n")} } sub insertText{ my $text = $_[0]; $ta->delete('insert','end'); $ta->insert('insert',$text); $ta->see('insert'); }

Thanks for your help on this one.

Update: Noticed a misstake in the calls to setStart.

Replies are listed 'Best First'.
Re: Tk marks and placing the cursor
by aquarium (Curate) on Oct 04, 2004 at 12:52 UTC
    you need to have separate text widgets for the username and password...otherwise you're dealing with one large text widget which, by default, let's people move around it freely (typing over stuff as they go), thus you lose control of their actions. in this way, you have no hope of extracting username/password. nice colors :)
      Thanks I'd sort of come to this conculsion myself and the logon process will need to be handled in a different way. However if you have ever seen a main frame session he are allowed to type anywhere in the screen and the command is picked up, that old stuffs quite cleaver really.
        afaik: those mainframe type screens do have different fields embedded, only you can move with the cursor keys inside each field and between the fields. if it's one text widget, you can type over or insert text right over your username/password labels or delete them entirely. so if a user makes the mistake of typing over the labels username/password, how are they supposed to know where the input area for those is?
Re: Tk marks and placing the cursor
by zentara (Cardinal) on Oct 04, 2004 at 13:50 UTC
    While it would be easier with a separate Entry widget, you should be able to do with Tk::Text. I don't have anything offhand to show you, but this has been asked on http://groups.google.com, just search for "perl Tk inertion cursor".

    The easiest would be to know where the cursor needs to be by line-position. For instance in your code:

    $ta->mark(qw/ set insert 2.15 /); MainLoop;
    will do it.

    But you could also figure out a tag scheme, where you tag your input boxes, and set insert to the tag point.


    I'm not really a human, but I play one on earth. flash japh