Saturday, November 03, 2012

Entry widget undo/redo in Tcl.

Hacked together a simple proof of method script to implement Undo/Redo functionality for the gnocl::entry widget. There are some improvements that can be done such as overloading the basic entry widget to allow undo/redo as a widget command. Keyboard bindings are fully there too. I'll take a look at these at a later time.



#---------------
# entryundo($ent)Redo.tcl
#---------------
# Created by William J Giddings
# October, 2012
#---------------
# Description:
# Demonstrates simple entry undo($ent)/redo functionality.
#---------------
# Notes:
# cd /Desktop/GnoclEdit_2/undo($ent)er/wjgstuff
#
# This version has a single buffer to show edit history
#
#---------------

# basic Tcl/Gnocl Script
#! /bin/sh/
#\
exec tclsh "$0" "$@"

package require Gnocl

#---------------
#
#---------------
#
proc entry:resetUndo {ent } {
    global undo idx
    set idx($ent) -1
    set undo($ent) ""
}

#---------------
#
#---------------
#
proc entry:undo {ent} {
    global idx undo
    incr idx($ent) -1
    if { $idx($ent) <= -1} {
        $ent configure -value ""
        set idx($ent) -1
        } else {
            $ent configure -value [lindex $undo($ent) $idx($ent)]
        }
    gnocl::update
}

#---------------
#
#---------------
#
proc entry:redo {ent} {
    global idx undo
    incr idx($ent)
    if { $idx($ent) >= [llength $undo($ent)] } { incr idx($ent) -1 }
    $ent configure -value [lindex $undo($ent) $idx($ent)]
    gnocl::update
}

#---------------
#
#---------------
#
proc entry:addUndo {ent} {
   
    global undo idx
   
    set undo($ent) ""
    set idx($ent) -1
   
    $ent configure -onKeyPress {
        if { "%s" == 20 && "%a" == "y" } { redo %w }
        if { "%s" == 20 && "%a" == "z" } { undo %w }
        set idx(%w) [llength $undo(%w)]
        incr idx(%w) -1
        }

    $ent configure -onKeyRelease {
        lappend undo(%w) [%w get]
        incr idx(%w)
        }

    $ent configure -onDestroy {
        puts "BYE BYE"
        array unset undo %w
        array unset idx %w
        }

}

set b(1) [gnocl::button -text Undo -onClicked { entry:undo $ent } ]
set b(2) [gnocl::button -text Redo -onClicked { entry:redo $ent } ]
set b(3) [gnocl::button -text Reset -onClicked { entry:resetUndo $ent }]
set ent [gnocl::entry]
set box [gnocl::box -orientation vertical]
$box add $b(1)
$box add $b(2)
$box add $b(3)
$box add $ent
gnocl::window -child $box

entry:addUndo $ent

No comments: