class Tkar::Canvas

Attributes

follow_id[RW]
zoom[R]

Public Class Methods

new(*) click to toggle source
Calls superclass method
   # File lib/tkar/canvas.rb
14 def initialize(*)
15   super
16 
17   @shapes = {}
18   @shape_def = {}
19   @zoom = 1.0
20   init_objects
21 end

Public Instance Methods

adjust_scrollregion() click to toggle source
   # File lib/tkar/canvas.rb
50 def adjust_scrollregion
51   configure :scrollregion => @bounds.map {|u|u*@zoom}
52   ## if all of canvas can be shown, hide the scroll bars
53 end
current_height() click to toggle source
    # File lib/tkar/canvas.rb
104 def current_height
105   Integer(TkWinfo.geometry(self)[/\d+x(\d+)/, 1])
106 end
current_width() click to toggle source
    # File lib/tkar/canvas.rb
100 def current_width
101   Integer(TkWinfo.geometry(self)[/\d+/])
102 end
init_objects() click to toggle source
   # File lib/tkar/canvas.rb
23 def init_objects
24   @objects = {}
25   @changed = {}
26   @layers = []            # sorted array of layer numbers
27   @objects_by_layer = {}  # layer => [obj, ...]
28   follow nil
29 end
scan_dragto(x, y, gain = 10) click to toggle source

fixes a bug in RubyTk

   # File lib/tkar/canvas.rb
88 def scan_dragto(x, y, gain = 10)
89   tk_send_without_enc('scan', 'dragto', x, y, gain)
90   self
91 end
view_followed_obj() click to toggle source
   # File lib/tkar/canvas.rb
93 def view_followed_obj
94   tkaroid = get_object(@follow_id)
95   if tkaroid
96     view_at(tkaroid.x + @follow_xdelta, tkaroid.y + @follow_ydelta)
97   end
98 end
xview(mode=nil, *args) click to toggle source
Calls superclass method
   # File lib/tkar/canvas.rb
55 def xview(mode=nil, *args)
56   if mode and mode == "scroll" and @follow_xdelta
57     number, what = args
58     x_pre, = xview
59     r = super(mode, *args)
60     x_post, = xview
61     x0,y0,x1,y1 = @bounds
62     @follow_xdelta += (x_post - x_pre) * (x1-x0)
63     r
64   elsif not mode
65     super()
66   else
67     super(mode, *args)
68   end
69 end
yview(mode=nil, *args) click to toggle source
Calls superclass method
   # File lib/tkar/canvas.rb
71 def yview(mode=nil, *args)
72   if mode and mode == "scroll" and @follow_ydelta
73     number, what = args
74     y_pre, = yview
75     r = super(mode, *args)
76     y_post, = yview
77     x0,y0,x1,y1 = @bounds
78     @follow_ydelta += (y_post - y_pre) * (y1-y0)
79     r
80   elsif not mode
81     super()
82   else
83     super(mode, *args)
84   end
85 end
zoom_by(zf) click to toggle source
   # File lib/tkar/canvas.rb
31 def zoom_by zf
32   zf = Float(zf)
33   @zoom *= zf
34   
35   vf = (1 - 1/zf) / 2
36   
37   x0, x1 = xview
38   xf = x0 + vf * (x1-x0)
39 
40   y0, y1 = yview
41   yf = y0 + vf * (y1-y0)
42 
43   scale 'all', 0, 0, zf, zf
44   adjust_scrollregion
45 
46   xview "moveto", xf
47   yview "moveto", yf
48 end

Commands

↑ top

Public Instance Methods

add(shape_name, tkar_id, flags, layer, x, y, r, *params) click to toggle source
    # File lib/tkar/canvas.rb
173 def add shape_name, tkar_id, flags, layer, x, y, r, *params
174   del(tkar_id)
175   
176   tkaroid = Tkaroid.new do |t|
177     t.shape   = get_shape(shape_name)
178     t.id      = tkar_id
179     t.flags   = flags
180     t.layer   = layer
181     t.x       = x
182     t.y       = y
183     t.r       = r
184     t.params  = params
185     t.newly_added = true
186   end
187 
188   @objects[tkar_id] = tkaroid
189   @changed[tkar_id] = tkaroid
190 end
bounds(x0,y0,x1,y1) click to toggle source
    # File lib/tkar/canvas.rb
352 def bounds x0,y0,x1,y1
353   @bounds = [x0,y0,x1,y1]
354   adjust_scrollregion
355 end
check_param(param) click to toggle source
    # File lib/tkar/canvas.rb
232 def check_param param
233   if param.nil?
234     nil
235   elsif param.is_a? String and param[0] == ?*
236     param_idx = Integer(param[1..-1])
237     proc {|param_array| param_array[param_idx]}
238   else
239     (Integer(param) rescue Float(param)) rescue param
240   end
241 end
compile_shape(defn) click to toggle source
    # File lib/tkar/canvas.rb
243 def compile_shape defn
244   part_spec_defs = defn.scan(/([_A-Za-z]+)([^;]*);?/)
245   
246   part_spec_defs.map do |prim_name, args|
247     args = args.split(",")
248     key_args, args = args.partition {|arg| /:/ =~ arg}
249 
250     macro = @shape_def[prim_name]
251     if macro
252       macro2 = macro.gsub(/\*\d+/) {|s| i=Integer(s[/\d+/]); args[i]}
253       macro2 = [macro2, *key_args].join(",")
254       compile_shape(macro2)
255     else
256       args.map! {|arg| check_param(arg)}
257       key_args.map! {|key_arg| key_arg.split(":")}
258       key_args.map! do |k, v|
259         [Primitives.handle_shortcuts(k), v]
260       end
261       key_args = key_args.inject({}) {|h,(k,v)| h[k] = check_param(v); h}
262       Primitives.send(prim_name, args, key_args)
263     end
264   end
265 end
del(tkar_id) click to toggle source

Not “delete”! That already exists in tk.

    # File lib/tkar/canvas.rb
193 def del tkar_id
194   tkaroid = @objects[tkar_id]
195   if tkaroid
196     if @follow_id == tkar_id
197       follow nil
198     end
199     delete tkaroid.tag
200     @objects.delete tkar_id
201     @changed.delete tkar_id
202     get_objects_by_layer(tkaroid.layer).delete tkaroid
203   end
204 end
delete_all() click to toggle source
    # File lib/tkar/canvas.rb
357 def delete_all
358   @objects.values.each do |tkaroid|
359     delete tkaroid.tag
360   end
361   init_objects
362 end
follow(id) click to toggle source
    # File lib/tkar/canvas.rb
346 def follow id
347   @follow_id = id
348   @follow_xdelta = id && 0
349   @follow_ydelta = id && 0
350 end
moveto(tkar_id, x, y) click to toggle source
    # File lib/tkar/canvas.rb
206 def moveto tkar_id, x, y
207   tkaroid = get_object(tkar_id)
208   unless tkaroid.x == x and tkaroid.y == y
209     tkaroid.x = x
210     tkaroid.y = y
211     @changed[tkar_id] = tkaroid
212   end
213 end
param(tkar_id, idx, val) click to toggle source
    # File lib/tkar/canvas.rb
223 def param tkar_id, idx, val
224   tkaroid = get_object(tkar_id)
225   params = tkaroid.params
226   unless params[idx] == val
227     tkaroid.params[idx] = val
228     @changed[tkar_id] = tkaroid
229   end
230 end
rot(tkar_id, r) click to toggle source
    # File lib/tkar/canvas.rb
215 def rot tkar_id, r
216   tkaroid = get_object(tkar_id)
217   unless tkaroid.r == r
218     tkaroid.r = r
219     @changed[tkar_id] = tkaroid
220   end
221 end
scale_obj(tkar_id, xf, yf) click to toggle source
    # File lib/tkar/canvas.rb
364 def scale_obj tkar_id, xf, yf
365   tkaroid = get_object(tkar_id)
366   z = @zoom
367   scale tkaroid.tag, tkaroid.x*z, tkaroid.y*z, xf, yf
368 end
shape(name, *defn) click to toggle source
    # File lib/tkar/canvas.rb
267 def shape name, *defn
268   defn = defn.join(";")
269   part_spec_makers = compile_shape(defn)
270   part_spec_makers.flatten!
271   @shape_def[name] = defn # should prevent inf recursion
272   
273   @shapes[name] = proc do |tkaroid|
274     cos_r = Math::cos(tkaroid.r)
275     sin_r = Math::sin(tkaroid.r)
276     
277     part_spec_makers.map do |maker|
278       maker[tkaroid, cos_r, sin_r]
279     end
280   end
281 end
title(str) click to toggle source
    # File lib/tkar/canvas.rb
303 def title str
304   @root.title str
305 end
update() click to toggle source
    # File lib/tkar/canvas.rb
283 def update
284   z = (zoom - 1).abs > 0.01 && zoom
285   
286   thread = Thread.current
287   pri = thread.priority
288   thread.priority += 10
289   
290   @changed.each do |tkar_id, tkaroid|
291     newly_added = tkaroid.update(self, z)
292     if newly_added
293       insert_at_layer(tkaroid)
294     end
295   end
296   @changed.clear
297 
298   view_followed_obj if @follow_id
299 ensure
300   thread.priority = pri if thread
301 end
view_at(x, y) click to toggle source
    # File lib/tkar/canvas.rb
322 def view_at x, y
323   x0,y0,x1,y1 = @bounds
324   width = TkWinfo.width(self)
325   height = TkWinfo.height(self)
326   xview "moveto", (x-x0-(width/(@zoom*2.0)))/(x1-x0).to_f
327   yview "moveto", (y-y0-(height/(@zoom*2.0)))/(y1-y0).to_f
328 end
view_at_screen(x,y) click to toggle source
    # File lib/tkar/canvas.rb
330 def view_at_screen x,y
331   view_at(canvasx(x)/@zoom, canvasy(y)/@zoom)
332 end
view_id(id) click to toggle source
    # File lib/tkar/canvas.rb
334 def view_id id
335   tkaroid = get_object(id)
336   view_at tkaroid.x, tkaroid.y if tkaroid
337 end
wait(t) click to toggle source
    # File lib/tkar/canvas.rb
339 def wait t
340   unless @timer
341     @timer = Timer.new(t)
342   end
343   @timer.wait(t)
344 end
window_xy(x,y) click to toggle source

background, height, width # already defined!

    # File lib/tkar/canvas.rb
309 def window_xy x,y
310   s = ""
311   s << "+" if x > 0
312   s << x.to_s
313   s << "+" if y > 0
314   s << y.to_s
315   @root.geometry s
316 end
zoom_to(z) click to toggle source
    # File lib/tkar/canvas.rb
318 def zoom_to z
319   zoom_by(z/@zoom)
320 end

Tkaroid manipulation commands

↑ top

Public Instance Methods

current_tkaroid() click to toggle source
    # File lib/tkar/canvas.rb
158 def current_tkaroid
159   object = find_withtag('current').first
160   if object
161     tags = object.tags
162     tkar_id = tags.grep(/^tkar\d+$/).first[/\d+/].to_i
163     @objects[tkar_id]
164   end
165 end
get_object(tkar_id) click to toggle source
    # File lib/tkar/canvas.rb
118 def get_object tkar_id
119   @objects[tkar_id] || (fail MissingObject, "No such object, #{tkar_id}")
120 end
get_objects_by_layer(layer) click to toggle source
    # File lib/tkar/canvas.rb
122 def get_objects_by_layer layer
123   ary = @objects_by_layer[layer]
124   unless ary
125     ary = @objects_by_layer[layer] = []
126     @layers << layer
127     @layers.sort!
128   end
129   ary
130 end
get_shape(name) click to toggle source
    # File lib/tkar/canvas.rb
114 def get_shape name
115   @shapes[name] || (fail MissingObject, "No such shape, #{name}")
116 end
insert_at_layer(tkaroid) click to toggle source
    # File lib/tkar/canvas.rb
132 def insert_at_layer tkaroid
133   layer = tkaroid.layer
134   peers = get_objects_by_layer(layer)
135   if peers.empty?
136     high = @layers.find {|l| l > layer}
137     if high
138       high_objects = get_objects_by_layer(high)
139       unless high_objects.empty?
140         lower tkaroid.tag, high_objects.first.tag
141       end
142     else
143       low = @layers.reverse.find {|l| l < layer}
144       if low
145         low_objects = get_objects_by_layer(low)
146         unless low_objects.empty?
147           raise tkaroid.tag, low_objects.last.tag
148         end
149       #else must be the only object!
150       end
151     end
152   else
153     raise tkaroid.tag, peers.last.tag
154   end
155   peers << tkaroid
156 end