if 0 { ''[escargo] 18 Jan 2005'' - I used [wish-reaper] to download this to my [Windows] XP Pro system. No ants marched. [DKF]: IIRC, Tk on Win has a few deficiencies in the dash handling... :^( [MM] See [Canvas dash lines]. [HJG] and [Dash lines on Windows] ---- } # canvas_marching_ants.tcl -- # # Part of: Useless Widgets Package # Contents: test script for the marching ants selection # Date: Mon Jan 17, 2005 # # Abstract # # Selects items with the marching ants. # # Copyright (c) 2005 Marco Maggi # # Most of [uwp_p_marching_ants_start_auto_scan] comes from the TK source # version 8.4, file "listbox.tcl". # # Copyright (c) 1994 The Regents of the University of California. # Copyright (c) 1994-1995 Sun Microsystems, Inc. # Copyright (c) 1998 by Scriptics Corporation. # # # 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.select_move_cursor fleur option add *Canvas.select_point_cursor hand1 option add *Canvas.marching_ant_pattern {10 4} option add *Canvas.marching_ant_step 4 option add *Canvas.marching_ant_select_color green option add *Canvas.marching_ant_marching_color red option add *Canvas.marching_ant_delay 300 #page ## ------------------------------------------------------------ ## Main. ## ------------------------------------------------------------ proc main {} { global exit_trigger wm title . "Canvas Marching Ants Selection" wm geometry . +200+100 frame .f canvas [set c .f.c] -width 300 -height 300 -background white \ -xscrollcommand {.f.hb set} -yscrollcommand {.f.vb set} scrollbar .f.vb -orient vertical -command {.f.c yview} scrollbar .f.hb -orient horizontal -command {.f.c xview} grid .f.c -sticky news -row 0 -column 0 grid .f.vb -sticky ns -row 0 -column 1 grid .f.hb -sticky ew -row 1 -column 0 listbox .l -background bisque grid .f .l -sticky news $c configure -scrollregion [list 0 0 400 400] $c create rectangle 20 20 60 60 -tags Rectangle $c create text 350 290 -text {This is some text} -tags Text $c create oval 50 50 80 80 -tags {"Little Circle"} $c create oval 50 50 120 120 -tags {"Medium Circle"} $c create oval 50 50 200 200 -tags {"Big Circle"} uwp_marching_ants_bind $c update_selection_list grid [button .quit -text Exit -command main_exit] focus .quit bind .quit main_exit bind . main_exit interp alias {} main_exit {} set exit_trigger 1 vwait exit_trigger exit } proc update_selection_list { widget selected_items_identifiers_list } { set selected_items_first_tags {} foreach item $selected_items_identifiers_list { lappend selected_items_first_tags [lindex [$widget gettags $item] 0] } .l delete 0 end eval {.l insert end} $selected_items_first_tags } #page proc uwp_data_set { widget key value } { global uwp_data set uwp_data($widget:$key) $value } 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 } #page bind MarchingAnts { uwp_marching_ants_event_press %W %x %y } bind MarchingAnts { uwp_marching_ants_event_release %W %x %y } bind MarchingAnts { uwp_marching_ants_event_release3 %W } bind MarchingAnts { uwp_marching_ants_event_enter %W } bind MarchingAnts { uwp_marching_ants_event_leave %W } bind MarchingAnts { uwp_marching_ants_event_pressed_and_leave %W } bind MarchingAntsSelect { uwp_marching_ants_event_motion %W %x %y } alias uwp_marching_ants_unbind uwp_p_remove_tag MarchingAnts alias uwp_marching_ants_bind_motion uwp_p_append_tag MarchingAntsSelect alias uwp_marching_ants_unbind_motion uwp_p_remove_tag MarchingAntsSelect proc uwp_marching_ants_bind { widget {command {}} } { uwp_p_append_tag MarchingAnts $widget uwp_data_set $widget MarchingAntsSelectCommand $command } #page proc uwp_marching_ants_event_press { widget x y } { uwp_p_marching_ants_delete_and_deselect_all $widget uwp_p_marching_ants_set_select_cursor $widget uwp_p_marching_ants_save_current_pointer_position $widget $x $y uwp_marching_ants_bind_motion $widget uwp_p_marching_ants_draw_selection_rectangle $widget $x $y } proc uwp_marching_ants_event_release { widget x y } { uwp_marching_ants_unbind_motion $widget uwp_p_marching_ants_set_point_cursor $widget uwp_p_marching_ants_delete_selection_rectangle $widget uwp_p_marching_ants_draw_marching_ants $widget $x $y uwp_p_marching_ants_select_items $widget uwp_p_marching_ants_stop_auto_scan $widget } proc uwp_marching_ants_event_release3 { widget } { uwp_p_marching_ants_delete_and_deselect_all $widget } proc uwp_marching_ants_event_enter { widget } { uwp_p_marching_ants_save_current_cursor $widget uwp_p_marching_ants_set_point_cursor $widget uwp_p_marching_ants_stop_auto_scan $widget } proc uwp_marching_ants_event_leave { widget } { uwp_p_marching_ants_restore_current_cursor $widget } proc uwp_marching_ants_event_motion { widget x y } { uwp_p_marching_ants_update_selection_rectangle_coords $widget $x $y } proc uwp_marching_ants_event_pressed_and_leave { widget args } { uwp_p_marching_ants_start_auto_scan $widget } #page proc uwp_p_marching_ants_save_current_pointer_position { widget spotX spotY } { uwp_data_set $widget spot \ [list [$widget canvasx $spotX] [$widget canvasy $spotY]] } proc uwp_p_marching_ants_save_current_cursor { widget } { uwp_data_set $widget oldCursor [. cget -cursor] } proc uwp_p_marching_ants_restore_current_cursor { widget } { . configure -cursor [uwp_data_get $widget oldCursor] } proc uwp_p_marching_ants_set_point_cursor { widget } { . configure -cursor [option get $widget select_point_cursor {}] } proc uwp_p_marching_ants_set_select_cursor { widget } { . configure -cursor [option get $widget select_move_cursor {}] } #page proc uwp_p_marching_ants_draw_selection_rectangle { widget x y } { foreach {spotX spotY} [uwp_data_get $widget spot] {} $widget create rectangle \ $spotX $spotY [$widget canvasx $x] [$widget canvasy $y] \ -tags SelectionRectangle \ -outline [option get $widget marching_ant_select_color {}] \ -dash [option get $widget marching_ant_pattern {}] } proc uwp_p_marching_ants_delete_selection_rectangle { widget } { $widget delete SelectionRectangle } proc uwp_p_marching_ants_update_selection_rectangle_coords { widget x y } { foreach {spotX spotY} [uwp_data_get $widget spot] {} $widget coords SelectionRectangle \ $spotX $spotY [$widget canvasx $x] [$widget canvasy $y] } #page proc uwp_p_marching_ants_draw_marching_ants { widget x y } { foreach {spotX spotY} [uwp_data_get $widget spot] {} $widget create rectangle \ $spotX $spotY [$widget canvasx $x] [$widget canvasy $y] \ -tags MarchingAnts \ -dash [option get $widget marching_ant_pattern {}] \ -outline [option get $widget marching_ant_marching_color {}] uwp_p_marching_ants_schedule_step $widget } proc uwp_p_marching_ants_delete_marching_ants { widget } { uwp_p_marching_ants_unschedule_step $widget $widget delete MarchingAnts } proc uwp_p_marching_ants_schedule_step { widget {step 0} } { uwp_data_set $widget MarchingAntsMarchAfterId \ [after [option get $widget marching_ant_delay {}] \ [list uwp_p_marching_ants_step $widget \ [incr step [option get $widget marching_ant_step {}]]]] } proc uwp_p_marching_ants_unschedule_step { widget } { catch {after cancel [uwp_data_get $widget MarchingAntsMarchAfterId]} } proc uwp_p_marching_ants_step { widget step } { if { [winfo exists $widget]} { $widget itemconfigure MarchingAnts -dashoffset $step uwp_p_marching_ants_schedule_step $widget $step } } proc uwp_p_marching_ants_delete_and_deselect_all { widget } { uwp_p_marching_ants_delete_selection_rectangle $widget uwp_p_marching_ants_delete_marching_ants $widget uwp_p_marching_ants_deselect_items $widget } #page proc uwp_p_marching_ants_select_items { widget } { eval {$widget addtag MarchingAntSelection enclosed} [$widget coords MarchingAnts] utp_p_marching_ants_invoke_selection_command $widget \ [$widget find withtag MarchingAntSelection] } proc uwp_p_marching_ants_deselect_items { widget } { $widget dtag MarchingAntSelection MarchingAntSelection utp_p_marching_ants_invoke_selection_command $widget {} } proc utp_p_marching_ants_invoke_selection_command { widget selected_items_tags } { set command [uwp_data_get $widget MarchingAntsSelectCommand] if { [string length $command] } { uplevel \#0 $command [list $widget $selected_items_tags] } } #page # Most of this comes from the TK source version 8.4, file "listbox.tcl". proc uwp_p_marching_ants_start_auto_scan { widget } { if { [winfo exists $widget] } { set x [expr [winfo pointerx $widget]-[winfo rootx $widget]] set y [expr [winfo pointery $widget]-[winfo rooty $widget]] if {$y >= [winfo height $widget]} { $widget yview scroll 1 units } elseif {$y < 0} { $widget yview scroll -1 units } elseif {$x >= [winfo width $widget]} { $widget xview scroll 1 units } elseif {$x < 0} { $widget xview scroll -1 units } else { return } uwp_data_set $widget MarchingAntsAutoScanAfterId \ [after 50 [list uwp_marching_ants_event_pressed_and_leave $widget]] } } proc uwp_p_marching_ants_stop_auto_scan { widget } { catch {after cancel [uwp_data_get $widget MarchingAntsAutoScanAfterId]} } #page ## ------------------------------------------------------------ ## Let's go. ## ------------------------------------------------------------ main ### end of file # Local Variables: # mode: tcl # End: ---- [[[Category GUI]]]