|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package require tkdnd |
|
namespace eval ::tkdnd { |
|
namespace eval utils { |
|
} |
|
namespace eval text { |
|
variable _drag_tag tkdnd::drag::selection::tag |
|
variable _state {} |
|
variable _drag_source_widget {} |
|
variable _drop_target_widget {} |
|
variable _now_dragging 0 |
|
} |
|
} |
|
|
|
bind TkDND_Drag_Text1 <ButtonPress-1> {tkdnd::text::_begin_drag clear 1 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text1 <B1-Motion> {tkdnd::text::_begin_drag motion 1 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text1 <B1-Leave> {tkdnd::text::_TextAutoScan %W %x %y} |
|
bind TkDND_Drag_Text1 <ButtonRelease-1> {tkdnd::text::_begin_drag reset 1 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text2 <ButtonPress-2> {tkdnd::text::_begin_drag clear 2 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text2 <B2-Motion> {tkdnd::text::_begin_drag motion 2 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text2 <ButtonRelease-2> {tkdnd::text::_begin_drag reset 2 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text3 <ButtonPress-3> {tkdnd::text::_begin_drag clear 3 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text3 <B3-Motion> {tkdnd::text::_begin_drag motion 3 %W %s %X %Y %x %y} |
|
bind TkDND_Drag_Text3 <ButtonRelease-3> {tkdnd::text::_begin_drag reset 3 %W %s %X %Y %x %y} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::drag_source { mode path { types DND_Text } { event 1 } { tagprefix TkDND_Drag_Text } { tag sel } } { |
|
switch -exact -- $mode { |
|
register { |
|
$path tag bind $tag <ButtonPress-${event}> \ |
|
"tkdnd::text::_begin_drag press ${event} %W %s %X %Y %x %y" |
|
|
|
bind $path <<DragInitCmd>> "::tkdnd::text::DragInitCmd $path {%t} $tag" |
|
|
|
bind $path <<DragEndCmd>> "::tkdnd::text::DragEndCmd $path %A $tag" |
|
} |
|
unregister { |
|
$path tag bind $tag <ButtonPress-${event}> {} |
|
bind $path <<DragInitCmd>> {} |
|
bind $path <<DragEndCmd>> {} |
|
} |
|
} |
|
::tkdnd::drag_source $mode $path $types $event $tagprefix |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::drop_target { mode path { types DND_Text } } { |
|
switch -exact -- $mode { |
|
register { |
|
bind $path <<DropPosition>> "::tkdnd::text::DropPosition $path %X %Y %A %a %m" |
|
bind $path <<Drop>> "::tkdnd::text::Drop $path %D %X %Y %A %a %m" |
|
} |
|
unregister { |
|
bind $path <<DropEnter>> {} |
|
bind $path <<DropPosition>> {} |
|
bind $path <<DropLeave>> {} |
|
bind $path <<Drop>> {} |
|
} |
|
} |
|
::tkdnd::drop_target $mode $path $types |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::DragInitCmd { path { types DND_Text } { tag sel } { actions { copy move } } } { |
|
|
|
variable _drag_source_widget |
|
variable _drop_target_widget |
|
set _drag_source_widget $path |
|
set _drop_target_widget {} |
|
_save_selection $path $tag |
|
list $actions $types [$path get $tag.first $tag.last] |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::DragEndCmd { path action { tag sel } } { |
|
variable _drag_source_widget |
|
variable _drop_target_widget |
|
set _drag_source_widget {} |
|
set _drop_target_widget {} |
|
_restore_selection $path $tag |
|
switch -exact -- $action { |
|
move { |
|
|
|
variable _selection_first |
|
variable _selection_last |
|
$path delete $_selection_first $_selection_last |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::DropPosition { path X Y action actions keys} { |
|
variable _drag_source_widget |
|
variable _drop_target_widget |
|
set _drop_target_widget $path |
|
|
|
if {$path eq $_drag_source_widget} { |
|
|
|
if {"move" in $actions} {set action move} |
|
} |
|
incr X -[winfo rootx $path] |
|
incr Y -[winfo rooty $path] |
|
$path mark set insert @$X,$Y; update |
|
return $action |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::Drop { path data X Y action actions keys } { |
|
incr X -[winfo rootx $path] |
|
incr Y -[winfo rooty $path] |
|
$path mark set insert @$X,$Y |
|
$path insert [$path index insert] $data |
|
return $action |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::_save_selection { path tag} { |
|
variable _drag_tag |
|
variable _selection_first |
|
variable _selection_last |
|
variable _selection_tag $tag |
|
set _selection_first [$path index $tag.first] |
|
set _selection_last [$path index $tag.last] |
|
$path tag add $_drag_tag $_selection_first $_selection_last |
|
$path tag configure $_drag_tag \ |
|
-background [$path tag cget $tag -background] \ |
|
-foreground [$path tag cget $tag -foreground] |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::_restore_selection { path tag} { |
|
variable _drag_tag |
|
variable _selection_first |
|
variable _selection_last |
|
$path tag delete $_drag_tag |
|
$path tag remove $tag 0.0 end |
|
|
|
} |
|
|
|
|
|
|
|
|
|
proc ::tkdnd::text::_begin_drag { event button source state X Y x y } { |
|
variable _drop_target_widget |
|
variable _state |
|
|
|
|
|
switch -exact -- $event { |
|
clear { |
|
switch -exact -- $_state { |
|
press { |
|
|
|
return -code break |
|
} |
|
} |
|
set _state clear |
|
} |
|
motion { |
|
variable _now_dragging |
|
if {$_now_dragging} {return -code break} |
|
if { [string equal $_state "press"] } { |
|
variable _x0; variable _y0 |
|
if { abs($_x0-$X) > ${::tkdnd::_dx} || abs($_y0-$Y) > ${::tkdnd::_dy} } { |
|
set _state "done" |
|
set _drop_target_widget {} |
|
set _now_dragging 1 |
|
set code [catch { |
|
::tkdnd::_init_drag $button $source $state $X $Y $x $y |
|
} info options] |
|
set _drop_target_widget {} |
|
set _now_dragging 0 |
|
if {$code != 0} { |
|
|
|
return -options $options $info |
|
} |
|
} |
|
return -code break |
|
} |
|
set _state clear |
|
} |
|
press { |
|
variable _x0; variable _y0 |
|
set _x0 $X |
|
set _y0 $Y |
|
set _state "press" |
|
} |
|
reset { |
|
set _state {} |
|
} |
|
} |
|
if {$source eq $_drop_target_widget} {return -code break} |
|
return -code continue |
|
} |
|
|
|
proc tkdnd::text::_TextAutoScan {w x y} { |
|
variable _now_dragging |
|
if {$_now_dragging} {return -code break} |
|
return -code continue |
|
} |
|
|