#
# Part of: Useless Widgets Package
# Contents: test script for object dropping
# Date: Wed Jan 19, 2005
#
# Abstract
#
# Drops objects on a canvas widget.
#
# Copyright (c) 2005 Marco Maggi
#
# The author hereby grant permission to use, copy, modify, distribute,
# and license this software and its documentation for any purpose,
# provided that existing copyright notices are retained in all copies
# and that this notice is included verbatim in any distributions. No
# written agreement, license, or royalty fee is required for any of the
# authorized uses. Modifications to this software may be copyrighted by
# their authors and need not follow the licensing terms described here,
# provided that the new terms are clearly indicated on the first page of
# each file where they apply.
#
# IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY
# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
# DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAVE BEEN ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
# NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# AND THE AUTHOR AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
# MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
#
#page
## ------------------------------------------------------------
## Setup.
## ------------------------------------------------------------
package require Tcl 8.4
package require Tk 8.4
#page
## ------------------------------------------------------------
## Widget options.
## ------------------------------------------------------------
option add *borderWidth 1
option add *Canvas.uwp_object_dropper_drop_cursor hand2
#page
## ------------------------------------------------------------
## Main.
## ------------------------------------------------------------
proc main {} {
global exit_trigger
wm title . "Canvas Objects Dropper"
wm geometry . +200+100
frame .f
canvas [set c .f.c] -width 300 -height 300 -background white
grid $c -sticky news -padx 5
uwp_object_dropper_bind $c
frame .radio
foreach { name } { oval rectangle none } {
grid [radiobutton .radio.$name -text [string totitle $name] \
-variable object -value $name -anchor w\
-command [list droppable_${name}_register $c]] -sticky news
}
.radio.none select
grid .f .radio -sticky news
grid [button .quit -text Exit -command main_exit]
focus .quit
bind .quit <Return> main_exit
bind . <Escape> main_exit
interp alias {} main_exit {} set exit_trigger 1
vwait exit_trigger
exit
}
#page
## ------------------------------------------------------------
## UWP infrastructure procedures.
## ------------------------------------------------------------
set uwp_counter 0
proc uwp_data_set { widget key value } {
global uwp_data
set uwp_data($widget:$key) $value
}
proc uwp_data_unset_by_pattern { widget args } {
global uwp_data
foreach key $args { array unset uwp_data $widget:$key* }
}
proc uwp_data_get { widget key } {
global uwp_data
return $uwp_data($widget:$key)
}
proc uwp_p_append_tag { tag widget } {
bindtags $widget [linsert [bindtags $widget] end $tag]
}
proc uwp_p_remove_tag { tag widget } {
set idx [lsearch [set ell [bindtags $widget]] $tag]
bindtags $widget [lreplace $ell $idx $idx]
}
proc alias { alias args } {
eval { interp alias {} $alias {} } $args
}
proc uwp_unique { } {
global uwp_counter
format "uwp__%d" [incr uwp_counter]
}
#page
## ------------------------------------------------------------
## Generic droppable object procedures.
## ------------------------------------------------------------
proc droppable_object_remove_from_canvas { token } {
upvar \#0 $token object
$object(CANVAS_WIDGET) delete $object(DELETE_TAG)
}
proc droppable_object_forget { token } {
uplevel \#0 [list unset $token]
}
proc droppable_none_register { canvas_widget } {
uwp_object_dropper_forget_object $canvas_widget
}
#page
## ------------------------------------------------------------
## Droppable oval procedures.
## ------------------------------------------------------------
proc droppable_oval_register { canvas_widget } {
upvar \#0 [set token [uwp_unique]] object
set object(CANVAS_WIDGET) $canvas_widget
set object(DRAW_SCRIPT) [list droppable_oval_draw_on_canvas $token]
set object(DELETE_SCRIPT) [list droppable_oval_remove_from_canvas $token]
set object(DROP_SCRIPT) [list droppable_oval_drop_on_canvas $token]
set object(FORGET_SCRIPT) [list droppable_oval_forget $token]
set object(DELETE_TAG) [uwp_unique]
uwp_object_dropper_register_object $canvas_widget $token
}
proc droppable_oval_draw_on_canvas { token spotX spotY } {
upvar \#0 $token object
set id [oval_draw $object(CANVAS_WIDGET) $spotX $spotY]
$object(CANVAS_WIDGET) itemconfigure $id -tags $object(DELETE_TAG)
}
proc droppable_oval_drop_on_canvas { token spotX spotY } {
upvar \#0 $token object
oval_draw $object(CANVAS_WIDGET) $spotX $spotY
}
alias droppable_oval_remove_from_canvas droppable_object_remove_from_canvas
alias droppable_oval_forget droppable_object_forget
proc oval_draw { canvas_widget upper_left_X upper_left_Y } {
$canvas_widget create oval $upper_left_X $upper_left_Y \
[expr {$upper_left_X+40}] [expr {$upper_left_Y+40}]
}
#page
## ------------------------------------------------------------
## Droppable rectangle procedures.
## ------------------------------------------------------------
proc droppable_rectangle_register { canvas_widget } {
upvar \#0 [set token [uwp_unique]] object
set object(CANVAS_WIDGET) $canvas_widget
set object(DRAW_SCRIPT) [list droppable_rectangle_draw_on_canvas $token]
set object(DELETE_SCRIPT) [list droppable_rectangle_remove_from_canvas $token]
set object(DROP_SCRIPT) [list droppable_rectangle_drop_on_canvas $token]
set object(FORGET_SCRIPT) [list droppable_rectangle_forget $token]
set object(DELETE_TAG) [uwp_unique]
uwp_object_dropper_register_object $canvas_widget $token
}
proc droppable_rectangle_draw_on_canvas { token spotX spotY } {
upvar \#0 $token object
set id [rectangle_draw $object(CANVAS_WIDGET) $spotX $spotY]
$object(CANVAS_WIDGET) itemconfigure $id -tags $object(DELETE_TAG)
}
proc droppable_rectangle_drop_on_canvas { token spotX spotY } {
upvar \#0 $token object
rectangle_draw $object(CANVAS_WIDGET) $spotX $spotY
}
alias droppable_rectangle_remove_from_canvas droppable_object_remove_from_canvas
alias droppable_rectangle_forget droppable_object_forget
proc rectangle_draw { canvas_widget upper_left_X upper_left_Y } {
$canvas_widget create rectangle $upper_left_X $upper_left_Y \
[expr {$upper_left_X+100}] [expr {$upper_left_Y+40}]
}
#page
## ------------------------------------------------------------
## Object dropper tag bindings.
## ------------------------------------------------------------
bind ObjectDropper <ButtonRelease-1> { uwp_object_dropper_event_release %W %x %y }
bind ObjectDropper <Enter> { uwp_object_dropper_event_enter %W }
bind ObjectDropper <Leave> { uwp_object_dropper_event_leave %W }
bind ObjectDropper <Motion> { uwp_object_dropper_event_motion %W %x %y }
proc uwp_object_dropper_bind { widget } {
uwp_p_append_tag ObjectDropper $widget
uwp_object_dropper_forget_object $widget
}
proc uwp_object_dropper_unbind { widget } {
uwp_p_remove_tag ObjectDropper $widget
uwp_data_unset_by_pattern $widget UWPObjectDropper
}
#page
## ------------------------------------------------------------
## Object dropper object registration/unregistration procedures.
## ------------------------------------------------------------
proc uwp_object_dropper_register_object { widget token } {
uwp_data_set $widget UWPObjectDropperObjectToken $token
}
proc uwp_object_dropper_forget_object { widget } {
uwp_data_set $widget UWPObjectDropperObjectToken {}
}
proc uwp_object_dropper_an_object_is_registered { widget } {
string length [uwp_data_get $widget UWPObjectDropperObjectToken]
}
#page
## ------------------------------------------------------------
## Object dropper event handling procedures.
## ------------------------------------------------------------
proc uwp_object_dropper_event_enter { widget } {
if { [uwp_object_dropper_an_object_is_registered $widget] } {
uwp_p_object_dropper_save_current_cursor $widget
uwp_p_object_dropper_set_drop_cursor $widget
}
}
proc uwp_object_dropper_event_leave { widget } {
if { [uwp_object_dropper_an_object_is_registered $widget] } {
uwp_p_object_dropper_restore_current_cursor $widget
uwp_p_object_dropper_delete_object $widget
}
}
proc uwp_object_dropper_event_motion { widget clickX clickY } {
if { [uwp_object_dropper_an_object_is_registered $widget] } {
uwp_p_object_dropper_delete_object $widget
uwp_p_object_dropper_draw_object $widget \
[$widget canvasx $clickX] [$widget canvasy $clickY]
}
}
proc uwp_object_dropper_event_release { widget clickX clickY } {
if { [uwp_object_dropper_an_object_is_registered $widget] } {
uwp_p_object_dropper_drop_object $widget \
[$widget canvasx $clickX] [$widget canvasy $clickY]
uwp_p_object_dropper_restore_current_cursor $widget
after 100 [list uwp_p_object_dropper_after_dropping $widget]
}
}
proc uwp_p_object_dropper_after_dropping { widget } {
if { [winfo exists $widget] } { uwp_p_object_dropper_set_drop_cursor $widget }
}
#page
## ------------------------------------------------------------
## Object dropper pointer procedures.
## ------------------------------------------------------------
proc uwp_p_object_dropper_save_current_cursor { widget } {
uwp_data_set $widget UWPObjectDropperCursor [. cget -cursor]
}
proc uwp_p_object_dropper_restore_current_cursor { widget } {
. configure -cursor [uwp_data_get $widget UWPObjectDropperCursor]
}
proc uwp_p_object_dropper_set_drop_cursor { widget } {
. configure -cursor [option get $widget uwp_object_dropper_drop_cursor {}]
}
#page
## ------------------------------------------------------------
## Object dropper object interface procedures.
## ------------------------------------------------------------
proc uwp_p_object_dropper_access_object { canvas_widget } {
set token [uwp_data_get $canvas_widget UWPObjectDropperObjectToken]
uplevel [subst { upvar \#0 $token object; set token $token }]
}
proc uwp_p_object_dropper_invoke_object_script { script args } {
uplevel \#0 $script $args
}
proc uwp_p_object_dropper_draw_object { canvas_widget canvasX canvasY } {
uwp_p_object_dropper_access_object $canvas_widget
uwp_p_object_dropper_invoke_object_script $object(DRAW_SCRIPT) $canvasX $canvasY
}
proc uwp_p_object_dropper_delete_object { canvas_widget } {
uwp_p_object_dropper_access_object $canvas_widget
uwp_p_object_dropper_invoke_object_script $object(DELETE_SCRIPT)
}
proc uwp_p_object_dropper_drop_object { canvas_widget canvasX canvasY } {
uwp_p_object_dropper_access_object $canvas_widget
uwp_p_object_dropper_invoke_object_script $object(DROP_SCRIPT) $canvasX $canvasY
}
#page
## ------------------------------------------------------------
## Let's go.
## ------------------------------------------------------------
main
### end of file
# Local Variables:
# mode: tcl
# End:[Category GUI]

