I am trying to create an equation editor. Doing this is something that won't work with a text widget as it requires me to have multiple baselines to accommodate sub- and superscripts, as well as having multiple fonts.

I have a small example just to test how to use canvas directly as a text editor. I can handle taking in keystrokes and adding them to the text on the canvas in a text item. But I'm having a problem handling the keyboard arrow keys. Whenever I press the left arrow, the keystroke binding works correctly, but the entire canvas shifts to the right.

I'm hopeful that there will be some way to lock the canvas into place so it doesn't move, and I've looked at a number of ways at doing that, but nothing has worked for me so far. Note that it makes no difference if I bind the left arrow separately, or even if I bind the left arrow to the main window directly.

Are there any suggestions?

use strict; use warnings; use Tk; my $mw = MainWindow->new ; my $canvas ; my $text ; my $text_var = 'Canvas example' ; my $text_len = length( $text_var ) ; my $cur_pos = $text_len ; my $width = 200 ; my $height = 100 ; $mw->title( 'Canvas Example' ) ; $canvas = $mw->Canvas( -background => 'white', -width => $width, -height => $height, -scrollregion => [ 0, 0, 500, 500 ], ) ; $canvas->CanvasFocus() ; $text = $canvas->createText( 100, 90, -text => $text_var, -tags => 'title', ) ; $canvas->focus( $text ) ; $canvas->icursor( $text, $cur_pos ) ; $canvas->bind( 'title', '<KeyRelease>' => \&updater ) ; my $exit = $mw->Button( -text => 'Exit', -command => [$mw => 'destroy'], ) ; $canvas->pack; $exit->pack; ######### MainLoop; ######### #function to manipulate text in the field or to move cursor around sub updater { my ( $k ) = @_ ; my $e = $k->XEvent ; #get event object my $k_val = $e->N ; #get decimal equivalent my $k_str = $e->K ; #get ascii equivalent #print "updater $k_val\n" ; #should move the cursor to left in text if( $k_str eq 'Left' ) { $cur_pos = $cur_pos > 0 ? $cur_pos - 1 : 0 ; } elsif( $k_str eq 'Right' ) { $cur_pos = $cur_pos < length( $text_var ) ? $cur_pos + 1 : len +gth( $text_var ) ; } else{ #append new char to the text $text_var .= $k_str ; $text_len = length( $text_var ) ; $cur_pos++ ; #show updated text $canvas->itemconfigure( -text => $text_var, -tags => 'title', ) ; } $canvas->icursor( $text, $cur_pos ) ; }


In reply to Tk::Canvas' response to keystrokes by TomKane

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.