TimesliderView.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. #Copyright (C) 1998 by USC/ISI
  2. # All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms are permitted
  5. # provided that the above copyright notice and this paragraph are
  6. # duplicated in all such forms and that any documentation, advertising
  7. # materials, and other materials related to such distribution and use
  8. # acknowledge that the software was developed by the University of
  9. # Southern California, Information Sciences Institute.  The name of the
  10. # University may not be used to endorse or promote products derived from
  11. # this software without specific prior written permission.
  12. #
  13. # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
  14. # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  15. # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16. #
  17. Class TimesliderView -superclass Observer
  18. TimesliderView instproc frame {} {
  19. $self instvar timeslider
  20. return $timeslider(frame)
  21. }
  22. TimesliderView instproc swidth {} {
  23. $self instvar timeslider
  24. return $timeslider(swidth)
  25. }
  26. #-----------------------------------------------------------------------
  27. #-----------------------------------------------------------------------
  28. TimesliderView instproc init {w mid} {
  29. $self next
  30. $self instvar timeslider timeslider_width timeslider_tag 
  31.               timeslider_pos range mid_ window_frame_ 
  32.               marker_id_counter_ delete_marker_
  33. set mid_ $mid
  34. set mintime [$mid_ getmintime]
  35. set maxtime [$mid_ getmaxtime]
  36. set range [expr $maxtime - $mintime]
  37. set marker_id_counter_ 0
  38. set delete_marker_ 0
  39. set window_frame_ $w.f
  40. frame $w.f -borderwidth 2 -relief groove
  41. pack $w.f -side top -fill x -expand 1 
  42. set timeslider(height) 24
  43. set timeslider(swidth) 32
  44. set timeslider(width) 32 
  45. set timeslider_width($w.f.c) 32
  46. set timeslider(canvas) $w.f.c
  47. set timeslider(frame) $w 
  48. # Create canvas for timeslider
  49. canvas $w.f.c -height $timeslider(height) -width 300 
  50.               -background white -highlightthickness 0
  51. pack $w.f.c -side left -fill x -expand 1 -padx 0 -pady 0
  52. label $w.f.c.b -bitmap time -highlightthickness 0 -borderwidth 1 
  53.                -relief raised
  54. set timeslider_tag($w.f.c) [$w.f.c create window 
  55.                            [expr $timeslider(swidth)/2] 0 -window $w.f.c.b 
  56.                            -height 12 -width $timeslider(swidth) -anchor n]
  57. set timeslider_pos($w.f.c) 0
  58. bind $w.f.c <ButtonPress-1> "$self timeslidertrough $w.f.c %x %y"
  59. bind $w.f.c.b <ButtonPress-1> "$self timesliderpress $w.f.c %x %y;break"
  60. bind $w.f.c.b <ButtonRelease-1> "$self timesliderrelease $w.f.c %x %y"
  61. bind $w.f.c.b <B1-Motion> "$self timeslidermotion $w.f.c %x %y"
  62. bind $w.f.c <Configure> "$self timeticks $w.f.c"
  63. }
  64. TimesliderView instproc destroy {} {
  65.   $self instvar window_frame_
  66.   if {[winfo exists $window_frame_]} {
  67.     # Need to delete old properties widgets
  68.     foreach widget [pack slaves $window_frame_] {
  69.       # Each property has a frame for it's line(ie. label textbox)
  70.       set subwidgets [pack slaves $widget]
  71.       if {[llength $subwidgets] > 0} {
  72.         pack forget $subwidgets
  73.         destroy $subwidgets
  74.       }
  75.       pack forget $widget
  76.       destroy $widget
  77.     }
  78.   }
  79.   catch {destroy $window_frame_}
  80.   $self next
  81. }
  82. #-----------------------------------------------------------------------
  83. # TimesliderView instproc timeticks { wfc }
  84. #   - Draws the timeslider tick marks into the canvas wfc
  85. #-----------------------------------------------------------------------
  86. TimesliderView instproc timeticks { wfc } {
  87. $self instvar timeslider range timeslider_width 
  88.               timeslider_tag mid_ 
  89. set timeslider(canvas) $wfc
  90. set width [winfo width $timeslider(canvas)]
  91. # if {$width == $timeslider_width($wfc)} { return }
  92. set mintime [$mid_ getmintime]
  93. set maxtime [$mid_ getmaxtime]
  94. set timeslider(width) $width
  95. set timeslider_width($wfc) $width
  96. $timeslider(canvas) delete ticks
  97. #we really shouldn't need to do this but there's a redraw bug in the
  98. #tk canvas that we need to work around (at least in tk4.2) - mjh
  99. pack forget $timeslider(canvas)
  100. update
  101. update idletasks
  102. pack $timeslider(canvas) -side left -fill x -expand 1 -padx 0 -pady 0
  103. set width [winfo width $wfc]
  104. # We need a more adaptive way to draw the ticks. Otherwise for long
  105. # and sparse simulations, it'll result in long startup time - haoboy
  106. set x [expr $timeslider(swidth)/2]
  107. # Unit of time represented by one pixel
  108. set tickIncr [expr $range / ($width-$timeslider(swidth))]
  109. # Should check if range is 0
  110. if {$range == 0} {
  111. set intertick [expr ($width - $timeslider(swidth)) / 10]
  112. } else {
  113. set intertick [expr ($width-$timeslider(swidth))/(10 * $range)]
  114. }
  115. if {$intertick < 2} {
  116. # This increment should be at least 2 pixel
  117. set intertick 2
  118. }
  119. for {set t $mintime} {$t < ($range+$mintime)} {set t [expr $t+$intertick*$tickIncr]} {
  120. set intx [expr int($x)]
  121. $timeslider(canvas) addtag ticks withtag 
  122.                    [$timeslider(canvas) create line 
  123.                    $intx [expr $timeslider(height)/2] 
  124.                    $intx $timeslider(height)]
  125. set x [expr $x+$intertick]
  126. }
  127. set x [expr $timeslider(swidth)/2]
  128. if {$range == 0} {
  129. set intertick [expr $width - $timeslider(swidth)]
  130. } else {
  131. set intertick [expr ($width-$timeslider(swidth))/($range)]
  132. }
  133. if {$intertick < 20} {
  134. set intertick 20
  135. }
  136. # Draw longer time marks
  137. for {set t $mintime} {$t < ($range+$mintime)} {set t [expr $t+$intertick*$tickIncr]} {
  138. set intx [expr int($x)]
  139. $timeslider(canvas) addtag ticks withtag 
  140.                    [$timeslider(canvas) create line 
  141.                    $intx 0 $intx $timeslider(height) -fill blue]
  142. set x [expr $x+$intertick]
  143. }
  144. # set arrow
  145. $timeslider(canvas) delete arrow
  146. set pmode [$mid_ getpipemode]
  147. if {$pmode == 1 } {
  148. set x [expr $width-$timeslider(swidth)/2]
  149. set y 0
  150. $timeslider(canvas) addtag arrow withtag 
  151.                    [$timeslider(canvas) create polygon $x $y 
  152.                    [expr $x+$timeslider(swidth)/2] [expr $y+$timeslider(height)/2] 
  153.                    $x [expr $y+$timeslider(height)]]
  154. }
  155. set wfc_width [winfo width $wfc]
  156. set now [$mid_ getcurrenttime]
  157. if {$maxtime > 0} {
  158. set x [expr ($wfc_width-$timeslider(swidth))*$now/$maxtime]
  159. } else {
  160. set x [expr ($wfc_width-$timeslider(swidth))*$now]
  161. }
  162. $wfc coords $timeslider_tag($wfc) [expr $x + $timeslider(swidth)/2] 0
  163. }
  164. #-----------------------------------------------------------------------
  165. # TimesliderView instproc timesliderpress {w x y}
  166. #   - Clicked on time slider's [ti^me] icon 
  167. #-----------------------------------------------------------------------
  168. TimesliderView instproc timesliderpress {w x y} {
  169. $self instvar timeslider mid_
  170. set timeslider(oldpos) $x
  171. $w.b configure -relief sunken
  172. set animator [$mid_ getanimator]
  173. $animator setsliderPressed 1
  174. }
  175. #-----------------------------------------------------------------------
  176. #-----------------------------------------------------------------------
  177. TimesliderView instproc timeslidertrough {w x y} {
  178. $self instvar timeslider sliderPressed timeslider_pos mid_
  179. set animator [$mid_ getanimator]
  180. if {$timeslider_pos($w)>$x} {
  181. $animator rewind
  182. } else {
  183. $animator fast_fwd
  184. }
  185. }
  186. #-----------------------------------------------------------------------
  187. #-----------------------------------------------------------------------
  188. TimesliderView instproc timeslidermotion {wc x y} {
  189.         $self instvar timeslider range timeslider_tag 
  190.                         timeslider_pos timeslider_width mid_
  191.     set mintime [$mid_ getmintime]
  192.     set diff [expr $x - $timeslider(oldpos)]
  193.     set timeslider(canvas) $wc
  194.     $timeslider(canvas) move $timeslider_tag($wc) 
  195.                 $diff 0
  196.     set timeslider_pos($wc) [expr $timeslider_pos($wc) + $diff]
  197.     if {$timeslider_pos($wc)<0} {
  198.         $timeslider(canvas) move $timeslider_tag($wc) 
  199.                 [expr 0 - $timeslider_pos($wc)] 0
  200.         set timeslider_pos($wc) 0
  201.     }
  202.     if {$timeslider_pos($wc)>[expr $timeslider_width($wc)-$timeslider(swidth)]} {
  203.         $timeslider(canvas) move $timeslider_tag($wc) 
  204.                 [expr ($timeslider_width($wc)-$timeslider(swidth))-$timeslider_pos($wc)] 0
  205.         set timeslider_pos($wc) [expr $timeslider_width($wc)-$timeslider(swidth)]
  206.     }
  207.     set tick 0
  208.     catch {
  209.         set tick [expr 1000.0*$timeslider_pos($wc)/($timeslider_width($wc)-$timeslider(swidth))]
  210.     }
  211.     set now [expr ($tick * $range) / 1000. + $mintime]
  212.     set timeslider(tick) $tick
  213.     set animator [$mid_ getanimator]
  214.     $animator setCurrentTime [format %.6f $now]
  215.     $self timesliderset $now
  216. }
  217. TimesliderView instproc timesliderrelease {w x y} {
  218. $self instvar timeslider running mid_
  219. set animator [$mid_ getanimator]
  220. $self timeslidermotion $w $x $y
  221. $w.b configure -relief raised
  222. $animator slidetime $timeslider(tick) 1
  223. $animator setsliderPressed 0
  224. if [$animator getrunning] {
  225. $animator renderFrame
  226. }
  227. }
  228. TimesliderView instproc update { timeset } {
  229. $self instvar timeslider range mid_
  230. set time [lindex $timeset 0]
  231. set type [lindex $timeset 1]
  232. if {[string compare $type "now"] == 0} {
  233. $self timesliderset $time 
  234. }
  235. if {[string compare $type "min"] == 0} {
  236. $self timesliderset $time 
  237. }
  238. if {[string compare $type "max"] == 0} {
  239. set mintime [$mid_ getmintime]
  240. set range [expr $time - $mintime]
  241. $self timeticks $timeslider(canvas) 
  242. }
  243. }
  244. TimesliderView instproc timesliderset {time} {
  245. $self instvar timeslider timeslider_width timeslider_tag 
  246.               timeslider_pos mid_ range
  247. # mid_ is the TimesliderModel id
  248. set minimum_time [$mid_ getmintime]
  249.                         
  250. if {[winfo exists $timeslider(canvas)] == 1} {
  251. # Scale time value to appropriate x coordinate on timeslider canvas
  252. set x [expr ($timeslider_width($timeslider(canvas)) - $timeslider(swidth)) * 
  253.             ($time - $minimum_time)]
  254. if {$range > 0} {
  255. set x [expr $x / $range]
  256. } else {
  257. # puts "TimesliderView.tcl:timesliderset - range is $range"
  258. }
  259. $timeslider(canvas) coords 
  260.                     $timeslider_tag($timeslider(canvas)) 
  261.                     [expr $x + $timeslider(swidth)/2] 0
  262. set timeslider_pos($timeslider(canvas)) $x
  263. }
  264. }
  265. #-----------------------------------------------------------------------
  266. #-----------------------------------------------------------------------
  267. TimesliderView instproc addMarker {time label_text color} {
  268. $self instvar timeslider timeslider_width range mid_ 
  269.               marker_id_counter_ markers_
  270. set mintime [$mid_ getmintime]
  271. # ---------  This code taken from timeticks -----------------
  272. set width [winfo width $timeslider(canvas)]
  273. set x [expr $timeslider(swidth)/2]
  274. # Unit of time represented by one pixel
  275. set tickIncr [expr $range / ($width - $timeslider(swidth))]
  276. # Should check if range is 0
  277. if {$range == 0} {
  278. set intertick [expr ($width - $timeslider(swidth))]
  279. } else {
  280. set intertick [expr ($width - $timeslider(swidth))/$range]
  281. }
  282. if {$intertick < 2} {
  283. # This increment should be at least 2 pixel
  284. set intertick 2
  285. }
  286. # ------------------------------------------------------------
  287. set x [expr ($timeslider(swidth)/2) + ($intertick * ($time - $mintime))]
  288. set marker $timeslider(canvas).marker$marker_id_counter_
  289. set marker_id_counter_ [expr $marker_id_counter_ + 1]
  290. label $marker -text $label_text -relief raised -background $color
  291. $timeslider(canvas) create window $x [expr $timeslider(height)/2] 
  292.                     -window $marker 
  293.                     -height [expr $timeslider(height)/2] -width 15 
  294.                     -anchor n -tags markers
  295. set markers_($marker) "$time $label_text"
  296. bind $marker <ButtonPress-1> "$marker configure -relief sunken"
  297. bind $marker <ButtonRelease-1> "$marker configure -relief raised; 
  298.                                 $self handleMarkerClick $marker"
  299. bind $marker <B1-Motion> 
  300. }
  301. #-----------------------------------------------------------------------
  302. # TimesliderView instproc clearMarkers {} 
  303. #   - Removes all time markers from the time slider view
  304. #-----------------------------------------------------------------------
  305. TimesliderView instproc clearMarkers {} {
  306. $self instvar timeslider marker_id_counter_
  307. for {set id 0} {$id < $marker_id_counter_} {set id [expr $id + 1]} {
  308. destroy $timeslider(canvas).marker$id
  309. }
  310. $timeslider(canvas) delete markers
  311. set marker_id_counter_ 0
  312. }
  313. #-----------------------------------------------------------------------
  314. #-----------------------------------------------------------------------
  315. TimesliderView instproc handleMarkerClick {marker} {
  316. $self instvar delete_marker_ mid_ markers_
  317. set animator [$mid_ getanimator]
  318. set time [lindex $markers_($marker) 0]
  319. set label_text [lindex $markers_($marker) 1]
  320. if {$delete_marker_ != 1} {
  321.           $animator moveToMarkerTime $time
  322. } else {
  323. destroy $marker
  324. $animator removeMarker $time $label_text
  325. }
  326. }