# canvas_object_dropper.tcl --
# # 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: