# Selection chapter

# Bindings for cut and paste on a canvas.

proc SetupCanvasSelect { c } {
	# Create a canvas with a couple of objects
	canvas $c
	pack $c
	$c create rect 10 10 50 50 -fill red -tag object
	$c create poly 100 100 100 30 140 50 -fill orange \
		-tag object
	# Set up cut and paste bindings
	$c bind object <1> [list CanvasSelect $c %x %y]
	$c bind object <3> [list CanvasCut $c %x %y]
	bind $c <2> [list CanvasPaste $c %x %y]
	selection handle $c [list CanvasSelectHandle $c]
}

proc CanvasSelect { w x y } {
	global canvas
	set id [$w find closest $x $y]
	set canvas(select,$w) $id
	selection own -command [list CanvasSelectLose $w] $w
}

proc CanvasCut { w x y } {
	global canvas
	set id [$w find closest $x $y]
	selection clear
	clipboard clear
	clipboard append [CanvasDescription $w $id]
	$w delete $id
}

proc CanvasSelectHandle { w offset maxbytes } {
	global canvas
	if ![info exists canvas(select,$w)] {
		error "No selected item"
	}
	set id $canvas(select,$w)
	return [string range [CanvasDescription $w $id] \
		$offset [expr $offset+$maxbytes]]
}
proc CanvasDescription { w id } {
	set type [$w type $id]
	set coords [$w coords $id]
	set config {}
	foreach conf [$w itemconfigure $id] {
		set default [lindex $conf 3]
		set value [lindex $conf 4]
		if {[string compare $default $value] != 0} {
			append config [list [lindex $conf 0] $value]  " "
		}
	}
	return [concat CanvasObject $type $coords $config]
}

proc CanvasSelectLose { w } {
	global canvas
	unset canvas(select,$w)
}

proc CanvasPaste { w x y } {
	if [catch {selection get} sel] {
		if [catch {selection get -selection CLIPBOARD} sel] {
			# no selection or clipboard data
		}
	}
	if [regexp {^CanvasObject} $sel] {
		if [catch {eval {$w create} [lrange $sel 1 end]} id] {
			return;
		}
		# look at the first coordinate to see where to
		# move the object.  Element 1 is the type, the
		# next two are the first coordinate
		set x1 [lindex $sel 2]
		set y1 [lindex $sel 3]
		$w move $id [expr $x-$x1] [expr $y-$y1]
	}
}
