dragsite.tcl 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # ------------------------------------------------------------------------------
  2. # dragsite.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # $Id$
  5. # ------------------------------------------------------------------------------
  6. # Index of commands:
  7. # - DragSite::include
  8. # - DragSite::setdrag
  9. # - DragSite::register
  10. # - DragSite::_begin_drag
  11. # - DragSite::_init_drag
  12. # - DragSite::_end_drag
  13. # - DragSite::_update_operation
  14. # ------------------------------------------------------------------------------
  15. namespace eval DragSite {
  16. Widget::declare DragSite {
  17. {-dragevent Enum 1 0 {1 2 3}}
  18. {-draginitcmd String "" 0}
  19. {-dragendcmd String "" 0}
  20. }
  21. variable _topw ".drag"
  22. variable _tabops
  23. variable _state
  24. variable _x0
  25. variable _y0
  26. bind BwDrag1 <ButtonPress-1> {DragSite::_begin_drag press %W %s %X %Y}
  27. bind BwDrag1 <B1-Motion> {DragSite::_begin_drag motion %W %s %X %Y}
  28. bind BwDrag2 <ButtonPress-2> {DragSite::_begin_drag press %W %s %X %Y}
  29. bind BwDrag2 <B2-Motion> {DragSite::_begin_drag motion %W %s %X %Y}
  30. bind BwDrag3 <ButtonPress-3> {DragSite::_begin_drag press %W %s %X %Y}
  31. bind BwDrag3 <B3-Motion> {DragSite::_begin_drag motion %W %s %X %Y}
  32. proc use {} {}
  33. }
  34. # ------------------------------------------------------------------------------
  35. # Command DragSite::include
  36. # ------------------------------------------------------------------------------
  37. proc DragSite::include { class type event } {
  38. set dragoptions {
  39. {-dragenabled Boolean 0 0}
  40. {-draginitcmd String "" 0}
  41. {-dragendcmd String "" 0}
  42. }
  43. lappend dragoptions \
  44. [list -dragtype String $type 0] \
  45. [list -dragevent Enum $event 0 {1 2 3}]
  46. Widget::declare $class $dragoptions
  47. }
  48. # ------------------------------------------------------------------------------
  49. # Command DragSite::setdrag
  50. # Widget interface to register
  51. # ------------------------------------------------------------------------------
  52. proc DragSite::setdrag { path subpath initcmd endcmd {force 0}} {
  53. set cen [Widget::hasChanged $path -dragenabled en]
  54. set cdragevt [Widget::hasChanged $path -dragevent dragevt]
  55. if { $en } {
  56. if { $force || $cen || $cdragevt } {
  57. register $subpath \
  58. -draginitcmd $initcmd \
  59. -dragendcmd $endcmd \
  60. -dragevent $dragevt
  61. }
  62. } else {
  63. register $subpath
  64. }
  65. }
  66. # ------------------------------------------------------------------------------
  67. # Command DragSite::register
  68. # ------------------------------------------------------------------------------
  69. proc DragSite::register { path args } {
  70. upvar \#0 DragSite::$path drag
  71. if { [info exists drag] } {
  72. bind $path $drag(evt) {}
  73. unset drag
  74. }
  75. Widget::init DragSite .drag$path $args
  76. set event [Widget::getoption .drag$path -dragevent]
  77. set initcmd [Widget::getoption .drag$path -draginitcmd]
  78. set endcmd [Widget::getoption .drag$path -dragendcmd]
  79. set tags [bindtags $path]
  80. set idx [lsearch $tags "BwDrag*"]
  81. Widget::destroy .drag$path
  82. if { $initcmd != "" } {
  83. if { $idx != -1 } {
  84. bindtags $path [lreplace $tags $idx $idx BwDrag$event]
  85. } else {
  86. bindtags $path [concat $tags BwDrag$event]
  87. }
  88. set drag(initcmd) $initcmd
  89. set drag(endcmd) $endcmd
  90. set drag(evt) $event
  91. } elseif { $idx != -1 } {
  92. bindtags $path [lreplace $tags $idx $idx]
  93. }
  94. }
  95. # ------------------------------------------------------------------------------
  96. # Command DragSite::_begin_drag
  97. # ------------------------------------------------------------------------------
  98. proc DragSite::_begin_drag { event source state X Y } {
  99. variable _x0
  100. variable _y0
  101. variable _state
  102. switch -- $event {
  103. press {
  104. set _x0 $X
  105. set _y0 $Y
  106. set _state "press"
  107. }
  108. motion {
  109. catch { if { ![string compare $_state "press"] } {
  110. if { abs($_x0-$X) > 3 || abs($_y0-$Y) > 3 } {
  111. set _state "done"
  112. _init_drag $source $state $X $Y
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. # ------------------------------------------------------------------------------
  120. # Command DragSite::_init_drag
  121. # ------------------------------------------------------------------------------
  122. proc DragSite::_init_drag { source state X Y } {
  123. variable _topw
  124. upvar \#0 DragSite::$source drag
  125. destroy $_topw
  126. toplevel $_topw
  127. wm withdraw $_topw
  128. wm overrideredirect $_topw 1
  129. set info [uplevel \#0 $drag(initcmd) [list $source $X $Y .drag]]
  130. if { $info != "" } {
  131. set type [lindex $info 0]
  132. set ops [lindex $info 1]
  133. set data [lindex $info 2]
  134. if { [winfo children $_topw] == "" } {
  135. if { ![string compare $type "BITMAP"] || ![string compare $type "IMAGE"] } {
  136. label $_topw.l -image [Bitmap::get dragicon] -relief flat -bd 0
  137. } else {
  138. label $_topw.l -image [Bitmap::get dragfile] -relief flat -bd 0
  139. }
  140. pack $_topw.l
  141. }
  142. wm geometry $_topw +[expr $X+1]+[expr $Y+1]
  143. wm deiconify $_topw
  144. tkwait visibility $_topw
  145. BWidget::grab set $_topw
  146. BWidget::focus set $_topw
  147. bindtags $_topw [list $_topw DragTop]
  148. DropSite::_init_drag $_topw $drag(evt) $source $state $X $Y $type $ops $data
  149. } else {
  150. destroy $_topw
  151. }
  152. }
  153. # ------------------------------------------------------------------------------
  154. # Command DragSite::_end_drag
  155. # ------------------------------------------------------------------------------
  156. proc DragSite::_end_drag { source target op type data result } {
  157. variable _topw
  158. upvar \#0 DragSite::$source drag
  159. BWidget::grab release $_topw
  160. BWidget::focus release $_topw
  161. destroy $_topw
  162. if { $drag(endcmd) != "" } {
  163. uplevel \#0 $drag(endcmd) [list $source $target $op $type $data $result]
  164. }
  165. }