class Tkar::Window

Constants

HELP_ICON

Attributes

canvas[R]

Public Class Methods

new(root, opts) click to toggle source

cmds to show grid, save image, make movie preferences

    # File lib/tkar/window.rb
 21 def initialize root, opts
 22   @flip = opts["flip"]
 23   
 24   canvas_frame = TkFrame.new(root) do
 25     pack 'fill'=>'both', 'expand'=>true
 26     background "lightgray"
 27   end
 28   TkGrid.rowconfigure(canvas_frame, 0, 'weight'=>1, 'minsize'=>0)
 29   TkGrid.columnconfigure(canvas_frame, 0, 'weight'=>1, 'minsize'=>0)
 30 
 31   @canvas = canvas = Tkar::Canvas.new(canvas_frame) do
 32     @bounds = [-3000, -3000, 3000, 3000]
 33     background "gray"
 34     relief "sunken"
 35     width 100; height 100 ## user prefs?
 36     configure :scrollregion => @bounds
 37     xscrollincrement 1
 38     yscrollincrement 1
 39     grid(:in => canvas_frame,
 40       :row => 0, :column => 0, 
 41       :rowspan => 1, :columnspan => 1, :sticky => :news)
 42     @root = root
 43   end
 44   
 45   xscroll = TkScrollbar.new(canvas_frame) do
 46     background 'darkgray'
 47     width 10
 48     relief "sunken"
 49     command do |*args|
 50       canvas.xview *args
 51     end
 52     grid(:in => canvas_frame,
 53       :row => 1, :column => 0, 
 54       :rowspan => 1, :columnspan => 1, :sticky => :news)
 55     orient 'horiz'
 56   end
 57 
 58   yscroll = TkScrollbar.new(canvas_frame) do
 59     background 'darkgray'
 60     width 10
 61     relief "sunken"
 62     command do |*args|
 63       canvas.yview *args
 64     end
 65     grid(:in => canvas_frame,
 66       :row => 0, :column => 1, 
 67       :rowspan => 1, :columnspan => 1, :sticky => :news)
 68     orient 'vertical'
 69   end
 70 
 71   TkButton.new(canvas_frame) do
 72     image HELP_ICON
 73     compound :none
 74     relief "flat"
 75     command {HelpWindow.show}
 76     grid(:in => canvas_frame,
 77       :row => 1, :column => 1, 
 78       :rowspan => 1, :columnspan => 1, :sticky => :news)
 79   end
 80 
 81   canvas.xscrollcommand do |first, last|
 82     xscroll.set(first, last)
 83   end
 84   canvas.yscrollcommand do |first, last|
 85     yscroll.set(first, last)
 86   end
 87   
 88   root.bind "Key-Right" do
 89     canvas.xview "scroll", 10, "units"
 90   end
 91 
 92   root.bind "Key-Left" do
 93     canvas.xview "scroll", -10, "units"
 94   end
 95 
 96   root.bind "Key-Down" do
 97     canvas.yview "scroll", 10, "units"
 98   end
 99 
100   root.bind "Key-Up" do
101     canvas.yview "scroll", -10, "units"
102   end
103 
104   root.bind "Alt-Key-Right" do
105     canvas.xview "scroll", 1, "units"
106   end
107 
108   root.bind "Alt-Key-Left" do
109     canvas.xview "scroll", -1, "units"
110   end
111 
112   root.bind "Alt-Key-Down" do
113     canvas.yview "scroll", 1, "units"
114   end
115 
116   root.bind "Alt-Key-Up" do
117     canvas.yview "scroll", -1, "units"
118   end
119 
120   root.bind "Control-Up" do
121     canvas.zoom_by 0.75
122   end
123   
124   root.bind "Control-Down" do
125     canvas.zoom_by 1.5
126   end
127   
128   root.bind "Key-h" do
129     HelpWindow.show
130   end
131 
132   root.bind "Control-q" do
133     exit
134   end
135   
136   at_exit do
137     message_out "quit"
138   end
139   
140   drag_start = drag_dx = drag_dy = drag_tkaroid = click_tkaroid = nil
141   drop_target = nil
142   drag_timer = nil
143   
144   drag_proc = proc do |x, y|
145     if drop_target
146       drop_target.decolorize(canvas)
147       drop_target = nil # we'll check below if it still is
148     end
149 
150     tkaroid = canvas.current_tkaroid
151     if tkaroid and tkaroid.draggable?
152       drag_tkaroid = tkaroid
153       x0, y0 = drag_start
154 
155       drag_dx = (x-x0)/canvas.zoom
156       drag_dy = (y-y0)/canvas.zoom
157       new_x, new_y = tkaroid.x + drag_dx, tkaroid.y + drag_dy
158       canvas.moveto(tkaroid.id, new_x, new_y)
159       msg_x, msg_y = new_x, new_y
160       if @flip
161         msg_y = -msg_y
162       end
163       message_out "drag #{tkaroid.id} #{msg_x} #{msg_y}"
164       tkaroid.update(canvas)
165       tkaroid.drag_colorize(canvas)
166       drag_start = [x, y]
167 
168       cx = canvas.canvasx(x)
169       cy = canvas.canvasy(y)
170       closest = canvas.find_closest(cx, cy, 0, "all") # start at top
171       tags = closest.map {|prim|prim.tag}.flatten
172       if tags.include? "current"
173         closest = canvas.find_closest(cx, cy, 0, "current")
174         tags = closest.map {|prim|prim.tag}.flatten
175       end
176 
177       unless tags.include? "current"
178         tkar_id = tags.grep(/^tkar\d+$/).first[/\d+/].to_i
179         tgt = canvas.get_object tkar_id
180         if tgt.drop_target? and tgt != drag_tkaroid
181           drop_target = tgt
182           drop_target.hover_colorize(canvas)
183         end
184       end
185     end
186   end
187 
188   drag_outside = proc do |x, y|
189     drag_timer = TkTimer.new(50) do
190       # scroll canvas if out of window if needed
191       width = canvas.current_width
192       height = canvas.current_height
193       units = 10
194       xsi = canvas.cget("xscrollincrement")*units
195       ysi = canvas.cget("yscrollincrement")*units
196 
197       if x < 0
198         canvas.xview "scroll", -units, "units"
199         x = -xsi
200         if drag_start
201           x0,y0 = drag_start
202           drag_start = [x0 + xsi, y0]
203         end
204       end
205 
206       if x > width
207         canvas.xview "scroll", units, "units"
208         x = width + xsi
209         if drag_start
210           x0,y0 = drag_start
211           drag_start = [x0 - xsi, y0]
212         end
213       end
214 
215       if y < 0
216         canvas.yview "scroll", -units, "units"
217         y = -ysi
218         if drag_start
219           x0,y0 = drag_start
220           drag_start = [x0, y0 + ysi]
221         end
222       end
223 
224       if y > height
225         canvas.yview "scroll", units, "units"
226         y = height + ysi
227         if drag_start
228           x0,y0 = drag_start
229           drag_start = [x0, y0 - ysi]
230         end
231       end
232 
233       drag_proc[x,y] if drag_start
234     end
235     drag_timer.start
236   end
237 
238   canvas.bind('B1-Motion', '%x %y') do |x, y|
239     if drag_timer
240       drag_timer.stop
241       drag_timer = nil
242     end
243 
244     if x >= 0 and x <= canvas.current_width and
245        y >= 0 and y <= canvas.current_height
246       drag_proc[x,y] if drag_start
247     else
248       drag_outside[x,y] if drag_start
249     end
250   end
251 
252   canvas.bind('B1-ButtonRelease', '%x %y') do |x, y|
253     if drag_timer
254       drag_timer.stop
255       drag_timer = nil
256     end
257 
258     if drag_tkaroid
259       drag_tkaroid.hover_colorize(canvas)
260 
261       if drop_target
262         message_out "drop #{drag_tkaroid.id} #{drop_target.id}"
263         drop_target.decolorize(canvas)
264       else
265         message_out "drop #{drag_tkaroid.id}"
266       end
267 
268       # if mouse is now over a NEW object
269       #   leave the old object
270       #   enter the new object
271       # (since Tk doesn't seem to generate leave and enter events)
272       cx = canvas.canvasx(x)
273       cy = canvas.canvasy(y)
274       closest = canvas.find_closest(cx, cy, 0, "all") # start at top
275       tags = closest.map {|prim|prim.tag}.flatten
276       tkar_id = tags.grep(/^tkar\d+$/).first[/\d+/].to_i
277       top_tkaroid = canvas.get_object tkar_id
278       if top_tkaroid != drag_tkaroid
279         drag_tkaroid.update(canvas)
280         top_tkaroid.hover_colorize(canvas) if top_tkaroid
281       end
282       
283     elsif click_tkaroid
284       click_tkaroid.hover_colorize(canvas)
285     end
286 
287     drag_start = drag_dx = drag_dy = drag_tkaroid = drop_target = nil
288     click_tkaroid = nil
289   end
290   
291   zoom_start = nil
292   canvas.bind('2', '%x %y') {|x,y| zoom_start = y}
293   canvas.bind('B2-Motion', '%x %y') {|x,y|
294     canvas.zoom_by(1 + (y - zoom_start)/500.0)
295     zoom_start = y
296   }
297   
298   canvas.bind('3', '%x %y') {|x,y| canvas.scan_mark(x,y)}
299   canvas.bind('B3-Motion', '%x %y') {|x,y| canvas.scan_dragto(x,y,1)}
300   canvas.bind('Control-B3-Motion', '%x %y') {|x,y|
301     canvas.scan_dragto(x,y,3)}
302   
303   small_zoom = 0.95
304   large_zoom = 0.75
305   
306   canvas.bind('4') {canvas.zoom_by small_zoom}
307   canvas.bind('5') {canvas.zoom_by 1/small_zoom}
308 
309   # For X windows:
310   canvas.bind('Control-4') {canvas.zoom_by large_zoom}
311   canvas.bind('Control-5') {canvas.zoom_by 1/large_zoom}
312   
313   # For MSWindows:
314   root.bind('MouseWheel', "%D") { |delta|
315     canvas.zoom_by small_zoom**(delta/120)
316   }
317   root.bind('Control-MouseWheel', "%D") { |delta|
318     canvas.zoom_by large_zoom**(delta/120)
319   }
320 
321   canvas.bind('Control-1', '%x %y') do |x, y|
322     tkaroid = canvas.current_tkaroid
323     if tkaroid
324       # handled in itembind('Control-1')
325     else
326       canvas.follow(nil)
327       canvas.view_at_screen(x,y)
328     end
329   end
330   
331   canvas.itembind('all', '1', '%x %y') do |x, y|
332     tkaroid = canvas.current_tkaroid
333     if tkaroid
334       if tkaroid.draggable?
335         drag_start = [x, y]
336         tkaroid.drag_colorize(canvas)
337       end
338       message_out "click #{tkaroid.id}"
339     end
340     click_tkaroid = tkaroid
341   end
342 
343   canvas.itembind('all', 'Control-1', '%x %y') do |x, y|
344     tkaroid = canvas.current_tkaroid
345     if tkaroid
346       if tkaroid.id == canvas.follow_id
347         canvas.follow(nil)
348       else
349         canvas.follow(tkaroid.id)
350         canvas.view_followed_obj
351       end
352     end
353   end
354   
355   canvas.itembind('all', 'Double-1') do
356     tkaroid = canvas.current_tkaroid
357     message_out "doubleclick #{tkaroid.id}" if tkaroid
358   end
359 
360   canvas.itembind('all', 'Any-Enter') do
361     unless drag_start
362       tkaroid = canvas.current_tkaroid
363       if tkaroid
364         tkaroid.hover_colorize(canvas)
365       end
366     end
367   end
368   
369   canvas.itembind('all', 'Any-Leave') do
370     tkaroid = canvas.current_tkaroid
371     tkaroid.decolorize(canvas) if tkaroid
372   end
373 end

Public Instance Methods

def_message_out(&bl) click to toggle source
    # File lib/tkar/window.rb
379 def def_message_out(&bl)
380   @message_out = bl
381 end
message_out(msg) click to toggle source
    # File lib/tkar/window.rb
375 def message_out msg
376   @message_out[msg] if @message_out
377 end