DEFINITIONS
This source file includes following functions.
1 #
2 # tk.rb - Tk interface module using tcltklib
3 # $Date: 2002/06/28 14:40:25 $
4 # by Yukihiro Matsumoto <matz@netlab.jp>
5
6 # use Shigehiro's tcltklib
7 require "tcltklib"
8 require "tkutil"
9
10 module TkComm
11 WidgetClassNames = {}
12
13 None = Object.new
14 def None.to_s
15 'None'
16 end
17
18 Tk_CMDTBL = {}
19 Tk_WINDOWS = {}
20
21 def error_at
22 frames = caller()
23 frames.delete_if do |c|
24 c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+!
25 end
26 frames
27 end
28 private :error_at
29
30 def _genobj_for_tkwidget(path)
31 return TkRoot.new if path == '.'
32
33 begin
34 tk_class = TkCore::INTERP._invoke('winfo', 'class', path)
35 rescue
36 return path
37 end
38
39 ruby_class = WidgetClassNames[tk_class]
40 gen_class_name = ruby_class.name + 'GeneratedOnTk'
41 unless Object.const_defined? gen_class_name
42 eval "class #{gen_class_name}<#{ruby_class.name}
43 def initialize(path)
44 @path=path
45 Tk_WINDOWS[@path] = self
46 end
47 end"
48 end
49 eval "#{gen_class_name}.new('#{path}')"
50 end
51
52 def tk_tcl2ruby(val)
53 if val =~ /^rb_out (c\d+)/
54 return Tk_CMDTBL[$1]
55 end
56 if val.include? ?\s
57 return val.split.collect{|v| tk_tcl2ruby(v)}
58 end
59 case val
60 when /^@font/
61 TkFont.get_obj(val)
62 when /^-?\d+$/
63 val.to_i
64 when /^\./
65 Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val)
66 when / /
67 val.split.collect{|elt|
68 tk_tcl2ruby(elt)
69 }
70 when /^-?\d+\.\d*$/
71 val.to_f
72 else
73 val
74 end
75 end
76
77 def tk_split_list(str)
78 return [] if str == ""
79 idx = str.index('{')
80 while idx and idx > 0 and str[idx-1] == ?\\
81 idx = str.index('{', idx+1)
82 end
83 return tk_tcl2ruby(str) unless idx
84
85 list = tk_tcl2ruby(str[0,idx])
86 list = [] if list == ""
87 str = str[idx+1..-1]
88 i = -1
89 brace = 1
90 str.each_byte {|c|
91 i += 1
92 brace += 1 if c == ?{
93 brace -= 1 if c == ?}
94 break if brace == 0
95 }
96 if str[0, i] == ' '
97 list.push ' '
98 else
99 list.push tk_split_list(str[0, i])
100 end
101 list += tk_split_list(str[i+1..-1])
102 list
103 end
104
105 def tk_split_simplelist(str)
106 return [] if str == ""
107 idx = str.index('{')
108 while idx and idx > 0 and str[idx-1] == ?\\
109 idx = str.index('{', idx+1)
110 end
111 return str.split unless idx
112
113 list = str[0,idx].split
114 str = str[idx+1..-1]
115 i = -1
116 brace = 1
117 str.each_byte {|c|
118 i += 1
119 brace += 1 if c == ?{
120 brace -= 1 if c == ?}
121 break if brace == 0
122 }
123 if i == 0
124 list.push ''
125 elsif str[0, i] == ' '
126 list.push ' '
127 else
128 list.push str[0..i-1]
129 end
130 list += tk_split_simplelist(str[i+1..-1])
131 list
132 end
133 private :tk_tcl2ruby, :tk_split_list, :tk_split_simplelist
134
135 def _symbolkey2str(keys)
136 h = {}
137 keys.each{|key,value| h[key.to_s] = value}
138 h
139 end
140 private :_symbolkey2str
141
142 def hash_kv(keys)
143 conf = []
144 if keys and keys != None
145 for k, v in keys
146 conf.push("-#{k}")
147 conf.push(v)
148 end
149 end
150 conf
151 end
152 private :hash_kv
153
154 def array2tk_list(ary)
155 ary.collect{|e|
156 if e.kind_of? Array
157 "{#{array2tk_list(e)}}"
158 elsif e.kind_of? Hash
159 "{#{e.to_a.collect{|ee| array2tk_list(ee)}.join(' ')}}"
160 else
161 s = _get_eval_string(e)
162 (s.index(/\s/))? "{#{s}}": s
163 end
164 }.join(" ")
165 end
166 private :array2tk_list
167
168 def bool(val)
169 case val
170 when "1", 1, 'yes', 'true'
171 TRUE
172 else
173 FALSE
174 end
175 end
176 def number(val)
177 case val
178 when /^-?\d+$/
179 val.to_i
180 when /^-?\d+\.\d*$/
181 val.to_f
182 else
183 val
184 end
185 end
186 def string(val)
187 if val == "{}"
188 ''
189 elsif val[0] == ?{
190 val[1..-2]
191 else
192 val
193 end
194 end
195 def list(val)
196 tk_split_list(val).to_a
197 end
198 def window(val)
199 Tk_WINDOWS[val]
200 end
201 def procedure(val)
202 if val =~ /^rb_out (c\d+)/
203 Tk_CMDTBL[$1]
204 else
205 nil
206 end
207 end
208 private :bool, :number, :string, :list, :window, :procedure
209
210 def _get_eval_string(str)
211 return nil if str == None
212 if str.kind_of?(String)
213 # do nothing
214 elsif str.kind_of?(Symbol)
215 str = str.id2name
216 elsif str.kind_of?(Hash)
217 str = hash_kv(str).join(" ")
218 elsif str.kind_of?(Array)
219 str = array2tk_list(str)
220 elsif str.kind_of?(Proc)
221 str = install_cmd(str)
222 elsif str == nil
223 str = ""
224 elsif str == false
225 str = "0"
226 elsif str == true
227 str = "1"
228 elsif (str.respond_to?(:to_eval))
229 str = str.to_eval()
230 else
231 str = str.to_s()
232 end
233 return str
234 end
235 private :_get_eval_string
236
237 def ruby2tcl(v)
238 if v.kind_of?(Hash)
239 v = hash_kv(v)
240 v.flatten!
241 v.collect{|e|ruby2tcl(e)}
242 else
243 _get_eval_string(v)
244 end
245 end
246 private :ruby2tcl
247
248 Tk_IDs = [0, 0] # [0]-cmdid, [1]-winid
249 def _curr_cmd_id
250 id = format("c%.4d", Tk_IDs[0])
251 end
252 def _next_cmd_id
253 id = _curr_cmd_id
254 Tk_IDs[0] += 1
255 id
256 end
257 def install_cmd(cmd)
258 return '' if cmd == ''
259 id = _next_cmd_id
260 Tk_CMDTBL[id] = cmd
261 @cmdtbl = [] unless @cmdtbl
262 @cmdtbl.push id
263 return format("rb_out %s", id);
264 end
265 def uninstall_cmd(id)
266 id = $1 if /rb_out (c\d+)/ =~ id
267 Tk_CMDTBL[id] = nil
268 end
269 private :install_cmd, :uninstall_cmd
270
271 def install_win(ppath,name=nil)
272 if !name or name == ''
273 name = format("w%.4d", Tk_IDs[1])
274 Tk_IDs[1] += 1
275 end
276 if !ppath or ppath == "."
277 @path = format(".%s", name);
278 else
279 @path = format("%s.%s", ppath, name)
280 end
281 Tk_WINDOWS[@path] = self
282 end
283
284 def uninstall_win()
285 Tk_WINDOWS[@path] = nil
286 end
287
288 class Event
289 def initialize(seq,a,b,c,d,f,h,k,m,o,p,s,t,w,x,y,
290 aa,bb,dd,ee,kk,nn,rr,ss,tt,ww,xx,yy)
291 @serial = seq
292 @above = a
293 @num = b
294 @count = c
295 @detail = d
296 @focus = (f == 1)
297 @height = h
298 @keycode = k
299 @mode = m
300 @override = (o == 1)
301 @place = p
302 @state = s
303 @time = t
304 @width = w
305 @x = x
306 @y = y
307 @char = aa
308 @borderwidth = bb
309 @wheel_delta = dd
310 @send_event = (ee == 1)
311 @keysym = kk
312 @keysym_num = nn
313 @rootwin_id = rr
314 @subwindow = ss
315 @type = tt
316 @widget = ww
317 @x_root = xx
318 @y_root = yy
319 end
320 attr :serial
321 attr :above
322 attr :num
323 attr :count
324 attr :detail
325 attr :focus
326 attr :height
327 attr :keycode
328 attr :mode
329 attr :override
330 attr :place
331 attr :state
332 attr :time
333 attr :width
334 attr :x
335 attr :y
336 attr :char
337 attr :borderwidth
338 attr :wheel_delta
339 attr :send_event
340 attr :keysym
341 attr :keysym_num
342 attr :rootwin_id
343 attr :subwindow
344 attr :type
345 attr :widget
346 attr :x_root
347 attr :y_root
348 end
349
350 def install_bind(cmd, args=nil)
351 if args
352 id = install_cmd(proc{|*arg|
353 TkUtil.eval_cmd cmd, *arg
354 })
355 id + " " + args
356 else
357 id = install_cmd(proc{|arg|
358 TkUtil.eval_cmd cmd, Event.new(*arg)
359 })
360 id + ' %# %a %b %c %d %f %h %k %m %o %p %s %t %w %x %y' +
361 ' %A %B %D %E %K %N %R %S %T %W %X %Y'
362 end
363 end
364
365 def tk_event_sequence(context)
366 if context.kind_of? TkVirtualEvent
367 context = context.path
368 end
369 if context.kind_of? Array
370 context = context.collect{|ev|
371 if ev.kind_of? TkVirtualEvent
372 ev.path
373 else
374 ev
375 end
376 }.join("><")
377 end
378 if /,/ =~ context
379 context = context.split(/\s*,\s*/).join("><")
380 else
381 context
382 end
383 end
384
385 def _bind_core(mode, what, context, cmd, args=nil)
386 id = install_bind(cmd, args) if cmd
387 begin
388 tk_call(*(what + ["<#{tk_event_sequence(context)}>", mode + id]))
389 rescue
390 uninstall_cmd(id) if cmd
391 fail
392 end
393 end
394
395 def _bind(what, context, cmd, args=nil)
396 _bind_core('', what, context, cmd, args)
397 end
398
399 def _bind_append(what, context, cmd, args=nil)
400 _bind_core('+', what, context, cmd, args)
401 end
402
403 def _bind_remove(what, context)
404 tk_call(*(what + ["<#{tk_event_sequence(context)}>", '']))
405 end
406
407 def _bindinfo(what, context=nil)
408 if context
409 tk_call(*what+["<#{tk_event_sequence(context)}>"]).collect {|cmdline|
410 if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
411 [Tk_CMDTBL[$1], $2]
412 else
413 cmdline
414 end
415 }
416 else
417 tk_split_simplelist(tk_call(*what)).collect!{|seq|
418 l = seq.scan(/<*[^<>]+>*/).collect!{|subseq|
419 case (subseq)
420 when /^<<[^<>]+>>$/
421 TkVirtualEvent.getobj(subseq[1..-2])
422 when /^<[^<>]+>$/
423 subseq[1..-2]
424 else
425 subseq.split('')
426 end
427 }.flatten
428 (l.size == 1) ? l[0] : l
429 }
430 end
431 end
432 private :install_bind, :tk_event_sequence,
433 :_bind_core, :_bind, :_bind_append, :_bind_remove, :_bindinfo
434
435 def bind(tagOrClass, context, cmd=Proc.new, args=nil)
436 _bind(["bind", tagOrClass], context, cmd, args)
437 end
438
439 def bind_append(tagOrClass, context, cmd=Proc.new, args=nil)
440 _bind_append(["bind", tagOrClass], context, cmd, args)
441 end
442
443 def bind_remove(tagOrClass, context)
444 _bind_remove(['bind', tagOrClass], context)
445 end
446
447 def bindinfo(tagOrClass, context=nil)
448 _bindinfo(['bind', tagOrClass], context)
449 end
450
451 def bind_all(context, cmd=Proc.new, args=nil)
452 _bind(['bind', 'all'], context, cmd, args)
453 end
454
455 def bind_append_all(context, cmd=Proc.new, args=nil)
456 _bind_append(['bind', 'all'], context, cmd, args)
457 end
458
459 def bindinfo_all(context=nil)
460 _bindinfo(['bind', 'all'], context)
461 end
462
463 def pack(*args)
464 TkPack.configure(*args)
465 end
466
467 def grid(*args)
468 TkGrid.configure(*args)
469 end
470
471 def update(idle=nil)
472 if idle
473 tk_call 'update', 'idletasks'
474 else
475 tk_call 'update'
476 end
477 end
478
479 end
480
481 module TkCore
482 include TkComm
483 extend TkComm
484
485 INTERP = TclTkIp.new
486
487 INTERP._invoke("proc", "rb_out", "args", <<-'EOL')
488 regsub -all {!} $args {\\!} args
489 regsub -all "{" $args "\\{" args
490 if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} {
491 return -code $st $ret
492 } {
493 return $ret
494 }
495 EOL
496
497 EventFlag = TclTkLib::EventFlag
498
499 def callback_break
500 fail TkCallbackBreak, "Tk callback returns 'break' status"
501 end
502
503 def callback_continue
504 fail TkCallbackContinue, "Tk callback returns 'continue' status"
505 end
506
507 def after(ms, cmd=Proc.new)
508 myid = _curr_cmd_id
509 cmdid = install_cmd(cmd)
510 tk_call("after",ms,cmdid)
511 # return
512 # if false #defined? Thread
513 # Thread.start do
514 # ms = Float(ms)/1000
515 # ms = 10 if ms == 0
516 # sleep ms/1000
517 # cmd.call
518 # end
519 # else
520 # cmdid = install_cmd(cmd)
521 # tk_call("after",ms,cmdid)
522 # end
523 end
524
525 def after_idle(cmd=Proc.new)
526 myid = _curr_cmd_id
527 cmdid = install_cmd(cmd)
528 tk_call('after','idle',cmdid)
529 end
530
531 def clock_clicks(ms=nil)
532 if ms
533 tk_call('clock','clicks','-milliseconds').to_i
534 else
535 tk_call('clock','clicks').to_i
536 end
537 end
538
539 def clock_format(clk, form=nil)
540 if form
541 tk_call('clock','format',clk,'-format',form).to_i
542 else
543 tk_call('clock','format',clk).to_i
544 end
545 end
546
547 def clock_formatGMT(clk, form=nil)
548 if form
549 tk_call('clock','format',clk,'-format',form,'-gmt','1').to_i
550 else
551 tk_call('clock','format',clk,'-gmt','1').to_i
552 end
553 end
554
555 def clock_scan(str, base=nil)
556 if base
557 tk_call('clock','scan',str,'-base',base).to_i
558 else
559 tk_call('clock','scan',str).to_i
560 end
561 end
562
563 def clock_scanGMT(str, base=nil)
564 if base
565 tk_call('clock','scan',str,'-base',base,'-gmt','1').to_i
566 else
567 tk_call('clock','scan',str,'-gmt','1').to_i
568 end
569 end
570
571 def clock_seconds
572 tk_call('clock','seconds').to_i
573 end
574
575 def TkCore.callback(arg)
576 arg = Array(tk_split_list(arg))
577 _get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg))
578 end
579
580 def scaling(scale=nil)
581 if scale
582 tk_call('tk', 'scaling', scale)
583 else
584 Float(number(tk_call('tk', 'scaling')))
585 end
586 end
587 def scaling_displayof(win, scale=nil)
588 if scale
589 tk_call('tk', 'scaling', '-displayof', win, scale)
590 else
591 Float(number(tk_call('tk', '-displayof', win, 'scaling')))
592 end
593 end
594
595 def appname(name=None)
596 tk_call('tk', 'appname', name)
597 end
598
599 def appsend(interp, async, *args)
600 if async
601 tk_call('send', '-async', '--', interp, *args)
602 else
603 tk_call('send', '--', interp, *args)
604 end
605 end
606
607 def rb_appsend(interp, async, *args)
608 args = args.collect!{|c| _get_eval_string(c).gsub(/[][$"]/, '\\\\\&')}
609 args.push(').to_s"')
610 appsend(interp, async, 'ruby "(', *args)
611 end
612
613 def appsend_displayof(interp, win, async, *args)
614 win = '.' if win == nil
615 if async
616 tk_call('send', '-async', '-displayof', win, '--', interp, *args)
617 else
618 tk_call('send', '-displayor', win, '--', interp, *args)
619 end
620 end
621
622 def rb_appsend_displayof(interp, win, async, *args)
623 args = args.collect!{|c| _get_eval_string(c).gsub(/[][$"]/, '\\\\\&')}
624 args.push(').to_s"')
625 appsend_displayof(interp, win, async, 'ruby "(', *args)
626 end
627
628 def info(*args)
629 tk_call('info', *args)
630 end
631
632 def mainloop(check_root = true)
633 TclTkLib.mainloop(check_root)
634 end
635
636 def mainloop_watchdog(check_root = true)
637 TclTkLib.mainloop_watchdog(check_root)
638 end
639
640 def do_one_event(flag = 0)
641 TclTkLib.do_one_event(flag)
642 end
643
644 def set_eventloop_tick(timer_tick)
645 TclTkLib.set_eventloop_tick(timer_tick)
646 end
647
648 def get_eventloop_tick()
649 TclTkLib.get_eventloop_tick
650 end
651
652 def set_eventloop_weight(loop_max, no_event_tick)
653 TclTkLib.set_eventloop_weight(loop_max, no_event_tick)
654 end
655
656 def get_eventloop_weight()
657 TclTkLib.get_eventloop_weight
658 end
659
660 def restart(app_name = nil, use = nil)
661 tk_call('set', 'argv0', app_name) if app_name
662 if use
663 tk_call('set', 'argc', 2)
664 tk_call('set', 'argv', "-use #{use}")
665 end
666 TkCore::INTERP.restart
667 TkComm::Tk_CMDTBL.clear
668 TkComm::Tk_WINDOWS.clear
669 nil
670 end
671
672 def event_generate(window, context, keys=nil)
673 window = window.path if window.kind_of? TkObject
674 if keys
675 tk_call('event', 'generate', window,
676 "<#{tk_event_sequence(context)}>", *hash_kv(keys))
677 else
678 tk_call('event', 'generate', window, "<#{tk_event_sequence(context)}>")
679 end
680 end
681
682 def messageBox(keys)
683 tk_call 'tk_messageBox', *hash_kv(keys)
684 end
685
686 def getOpenFile(keys = nil)
687 tk_call 'tk_getOpenFile', *hash_kv(keys)
688 end
689
690 def getSaveFile(keys = nil)
691 tk_call 'tk_getSaveFile', *hash_kv(keys)
692 end
693
694 def chooseColor(keys = nil)
695 tk_call 'tk_chooseColor', *hash_kv(keys)
696 end
697
698 def chooseDirectory(keys = nil)
699 tk_call 'tk_chooseDirectory', *hash_kv(keys)
700 end
701
702 def tk_call(*args)
703 puts args.inspect if $DEBUG
704 args.collect! {|x|ruby2tcl(x)}
705 args.compact!
706 args.flatten!
707 print "=> ", args.join(" ").inspect, "\n" if $DEBUG
708 begin
709 res = INTERP._invoke(*args)
710 rescue NameError
711 err = $!
712 begin
713 args.unshift "unknown"
714 res = INTERP._invoke(*args)
715 rescue
716 fail unless /^invalid command/ =~ $!
717 fail err
718 end
719 end
720 if INTERP._return_value() != 0
721 fail RuntimeError, res, error_at
722 end
723 print "==> ", res.inspect, "\n" if $DEBUG
724 return res
725 end
726 end
727
728 module TkPackage
729 include TkCore
730 extend TkPackage
731
732 def add_path(path)
733 Tk::AUTO_PATH.value = Tk::AUTO_PATH.to_a << path
734 end
735
736 def forget(package)
737 tk_call('package', 'forget', package)
738 nil
739 end
740
741 def names
742 tk_split_simplelist(tk_call('package', 'names'))
743 end
744
745 def provide(package, version=nil)
746 if version
747 tk_call('package', 'provide', package, version)
748 nil
749 else
750 tk_call('package', 'provide', package)
751 end
752 end
753
754 def present(package, version=None)
755 tk_call('package', 'present', package, version)
756 end
757
758 def present_exact(package, version)
759 tk_call('package', 'present', '-exact', package, version)
760 end
761
762 def require(package, version=None)
763 tk_call('package', 'require', package, version)
764 end
765
766 def require_exact(package, version)
767 tk_call('package', 'require', '-exact', package, version)
768 end
769
770 def versions(package)
771 tk_split_simplelist(tk_call('package', 'versions', package))
772 end
773
774 def vcompare(version1, version2)
775 Integer(tk_call('package', 'vcompare', version1, version2))
776 end
777
778 def vsatisfies(version1, version2)
779 bool(tk_call('package', 'vsatisfies', version1, version2))
780 end
781 end
782
783 module Tk
784 include TkCore
785 extend Tk
786
787 TCL_VERSION = INTERP._invoke("info", "tclversion")
788 TK_VERSION = INTERP._invoke("set", "tk_version")
789
790 TCL_PATCHLEVEL = INTERP._invoke("info", "patchlevel")
791 TK_PATCHLEVEL = INTERP._invoke("set", "tk_patchLevel")
792
793 TCL_LIBRARY = INTERP._invoke("set", "tcl_library")
794 TK_LIBRARY = INTERP._invoke("set", "tk_library")
795 LIBRARY = INTERP._invoke("info", "library")
796
797 PLATFORM = Hash[*tk_split_simplelist(INTERP._eval('array get tcl_platform'))]
798
799 JAPANIZED_TK = (INTERP._invoke("info", "commands", "kanji") != "")
800
801 def root
802 TkRoot.new
803 end
804
805 def bell
806 tk_call 'bell'
807 end
808
809 def Tk.focus(display=nil)
810 if display == nil
811 r = tk_call('focus')
812 else
813 r = tk_call('focus', '-displayof', display)
814 end
815 tk_tcl2ruby(r)
816 end
817
818 def Tk.focus_lastfor(win)
819 tk_tcl2ruby(tk_call('focus', '-lastfor', win))
820 end
821
822 def Tk.strictMotif(bool=None)
823 bool(tk_call('set', 'tk_strictMotif', bool))
824 end
825
826 def Tk.show_kinsoku(mode='both')
827 begin
828 if /^8\.*/ === TK_VERSION && JAPANIZED_TK
829 tk_split_simplelist(tk_call('kinsoku', 'show', mode))
830 end
831 rescue
832 end
833 end
834 def Tk.add_kinsoku(chars, mode='both')
835 begin
836 if /^8\.*/ === TK_VERSION && JAPANIZED_TK
837 tk_split_simplelist(tk_call('kinsoku', 'add', mode,
838 *(chars.split(''))))
839 else
840 []
841 end
842 rescue
843 []
844 end
845 end
846 def Tk.delete_kinsoku(chars, mode='both')
847 begin
848 if /^8\.*/ === TK_VERSION && JAPANIZED_TK
849 tk_split_simplelist(tk_call('kinsoku', 'delete', mode,
850 *(chars.split(''))))
851 end
852 rescue
853 end
854 end
855
856 def Tk.toUTF8(str,encoding)
857 INTERP._toUTF8(str,encoding)
858 end
859
860 def Tk.fromUTF8(str,encoding)
861 INTERP._fromUTF8(str,encoding)
862 end
863
864 module Scrollable
865 def xscrollcommand(cmd=Proc.new)
866 configure_cmd 'xscrollcommand', cmd
867 end
868 def yscrollcommand(cmd=Proc.new)
869 configure_cmd 'yscrollcommand', cmd
870 end
871 def xview(*index)
872 v = tk_send('xview', *index)
873 list(v) if index.size == 0
874 end
875 def yview(*index)
876 v = tk_send('yview', *index)
877 list(v) if index.size == 0
878 end
879 def xscrollbar(bar=nil)
880 if bar
881 @xscrollbar = bar
882 @xscrollbar.orient 'horizontal'
883 self.xscrollcommand {|arg| @xscrollbar.set(*arg)}
884 @xscrollbar.command {|arg| self.xview(*arg)}
885 end
886 @xscrollbar
887 end
888 def yscrollbar(bar=nil)
889 if bar
890 @yscrollbar = bar
891 @yscrollbar.orient 'vertical'
892 self.yscrollcommand {|arg| @yscrollbar.set(*arg)}
893 @yscrollbar.command {|arg| self.yview(*arg)}
894 end
895 @yscrollbar
896 end
897 end
898
899 module Wm
900 include TkComm
901 def aspect(*args)
902 w = tk_call('wm', 'aspect', path, *args)
903 list(w) if args.length == 0
904 end
905 def client(name=None)
906 tk_call 'wm', 'client', path, name
907 end
908 def colormapwindows(*args)
909 list(tk_call('wm', 'colormapwindows', path, *args))
910 end
911 def wm_command(value=None)
912 string(tk_call('wm', 'command', path, value))
913 end
914 def deiconify
915 tk_call 'wm', 'deiconify', path
916 end
917 def focusmodel(*args)
918 tk_call 'wm', 'focusmodel', path, *args
919 end
920 def frame
921 tk_call('wm', 'frame', path)
922 end
923 def geometry(*args)
924 tk_call('wm', 'geometry', path, *args)
925 end
926 def grid(*args)
927 w = tk_call('wm', 'grid', path, *args)
928 list(w) if args.size == 0
929 end
930 def group(*args)
931 w = tk_call 'wm', 'group', path, *args
932 window(w) if args.size == 0
933 end
934 def iconbitmap(*args)
935 tk_call 'wm', 'iconbitmap', path, *args
936 end
937 def iconify
938 tk_call 'wm', 'iconify', path
939 end
940 def iconmask(*args)
941 tk_call 'wm', 'iconmask', path, *args
942 end
943 def iconname(*args)
944 tk_call 'wm', 'iconname', path, *args
945 end
946 def iconposition(*args)
947 w = tk_call('wm', 'iconposition', path, *args)
948 list(w) if args.size == 0
949 end
950 def iconwindow(*args)
951 w = tk_call('wm', 'iconwindow', path, *args)
952 window(w) if args.size == 0
953 end
954 def maxsize(*args)
955 w = tk_call('wm', 'maxsize', path, *args)
956 list(w) if args.size == 0
957 end
958 def minsize(*args)
959 w = tk_call('wm', 'minsize', path, *args)
960 list(w) if args.size == 0
961 end
962 def overrideredirect(bool=None)
963 if bool == None
964 bool(tk_call('wm', 'overrideredirect', path))
965 else
966 tk_call 'wm', 'overrideredirect', path, bool
967 end
968 end
969 def positionfrom(*args)
970 tk_call 'wm', 'positionfrom', path, *args
971 end
972 def protocol(name=nil, cmd=nil)
973 if cmd
974 tk_call('wm', 'protocol', path, name, cmd)
975 elsif name
976 result = tk_call('wm', 'protocol', path, name)
977 (result == "")? nil : tk_tcl2ruby(result)
978 else
979 tk_split_simplelist(tk_call('wm', 'protocol', path))
980 end
981 end
982 def resizable(*args)
983 w = tk_call('wm', 'resizable', path, *args)
984 if args.length == 0
985 list(w).collect{|e| bool(e)}
986 end
987 end
988 def sizefrom(*args)
989 tk_call('wm', 'sizefrom', path, *args)
990 end
991 def state(state=None)
992 tk_call 'wm', 'state', path, state
993 end
994 def title(*args)
995 tk_call 'wm', 'title', path, *args
996 end
997 def transient(*args)
998 window(tk_call('wm', 'transient', path, *args))
999 end
1000 def withdraw
1001 tk_call 'wm', 'withdraw', path
1002 end
1003 end
1004 end
1005
1006 ###########################################
1007 # convert kanji string to/from utf-8
1008 ###########################################
1009 if /^8\.[1-9]/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK
1010 class TclTkIp
1011 # from tkencoding.rb by ttate@jaist.ac.jp
1012 alias __eval _eval
1013 alias __invoke _invoke
1014 private :__eval
1015 private :__invoke
1016
1017 attr_accessor :encoding
1018
1019 def _eval(cmd)
1020 if @encoding
1021 _fromUTF8(__eval(_toUTF8(cmd, @encoding)), @encoding)
1022 else
1023 __eval(cmd)
1024 end
1025 end
1026
1027 def _invoke(*cmds)
1028 if @encoding
1029 cmds = cmds.collect{|cmd| _toUTF8(cmd, @encoding)}
1030 _fromUTF8(__invoke(*cmds), @encoding)
1031 else
1032 __invoke(*cmds)
1033 end
1034 end
1035 end
1036
1037 module Tk
1038 def encoding=(name)
1039 INTERP.encoding = name
1040 end
1041
1042 def encoding
1043 INTERP.encoding
1044 end
1045
1046 def encoding_names
1047 tk_split_simplelist(tk_call('encoding', 'names'))
1048 end
1049
1050 def encoding_system
1051 tk_call('encoding', 'system')
1052 end
1053
1054 def encoding_system=(enc)
1055 tk_call('encoding', 'system', enc)
1056 end
1057 end
1058
1059 # estimate encoding
1060 case $KCODE
1061 when /^e/i # EUC
1062 Tk.encoding = 'euc-jp'
1063 when /^s/i # SJIS
1064 Tk.encoding = 'shiftjis'
1065 when /^u/i # UTF8
1066 Tk.encoding = 'utf-8'
1067 else # NONE
1068 begin
1069 Tk.encoding = Tk.encoding_system
1070 rescue StandardError, NameError
1071 Tk.encoding = 'utf-8'
1072 end
1073 end
1074
1075 else
1076 # dummy methods
1077 module Tk
1078 def encoding=(name)
1079 nil
1080 end
1081 def encoding
1082 nil
1083 end
1084 def encoding_names
1085 nil
1086 end
1087 def encoding_system
1088 nil
1089 end
1090 def encoding_system=(enc)
1091 nil
1092 end
1093 end
1094 end
1095
1096 module TkBindCore
1097 def bind(context, cmd=Proc.new, args=nil)
1098 Tk.bind(to_eval, context, cmd, args)
1099 end
1100
1101 def bind_append(context, cmd=Proc.new, args=nil)
1102 Tk.bind_append(to_eval, context, cmd, args)
1103 end
1104
1105 def bind_remove(context)
1106 Tk.bind_remove(to_eval, context)
1107 end
1108
1109 def bindinfo(context=nil)
1110 Tk.bindinfo(to_eval, context)
1111 end
1112 end
1113
1114 class TkBindTag
1115 include TkBindCore
1116
1117 BTagID_TBL = {}
1118 Tk_BINDTAG_ID = ["btag00000"]
1119
1120 def TkBindTag.id2obj(id)
1121 BTagID_TBL[id]? BTagID_TBL[id]: id
1122 end
1123
1124 ALL = self.new
1125 ALL.instance_eval {
1126 @id = 'all'
1127 BTagID_TBL[@id] = self
1128 }
1129
1130 def initialize(*args)
1131 @id = Tk_BINDTAG_ID[0]
1132 Tk_BINDTAG_ID[0] = Tk_BINDTAG_ID[0].succ
1133 BTagID_TBL[@id] = self
1134 bind(*args) if args != []
1135 end
1136
1137 def to_eval
1138 @id
1139 end
1140
1141 def inspect
1142 format "#<TkBindTag: %s>", @id
1143 end
1144 end
1145
1146 class TkBindTagAll<TkBindTag
1147 def TkBindTagAll.new(*args)
1148 $stderr.puts "Warning: TkBindTagALL is obsolete. Use TkBindTag::ALL\n"
1149
1150 TkBindTag::ALL.bind(*args) if args != []
1151 TkBindTag::ALL
1152 end
1153 end
1154
1155 class TkVariable
1156 include Tk
1157 extend TkCore
1158
1159 TkVar_CB_TBL = {}
1160 Tk_VARIABLE_ID = ["v00000"]
1161
1162 INTERP._invoke("proc", "rb_var", "args", "ruby [format \"TkVariable.callback %%Q!%s!\" $args]")
1163
1164 def TkVariable.callback(args)
1165 name1,name2,op = tk_split_list(args)
1166 if TkVar_CB_TBL[name1]
1167 _get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op))
1168 else
1169 ''
1170 end
1171 end
1172
1173 def initialize(val="")
1174 @id = Tk_VARIABLE_ID[0]
1175 Tk_VARIABLE_ID[0] = Tk_VARIABLE_ID[0].succ
1176 if val == []
1177 INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)',
1178 @id, @id, @id))
1179 elsif val.kind_of?(Array)
1180 a = []
1181 val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
1182 s = '"' + a.join(" ").gsub(/[][$"]/, '\\\\\&') + '"'
1183 INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
1184 elsif val.kind_of?(Hash)
1185 s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
1186 .gsub(/[][$"]/, '\\\\\&') + '"'
1187 INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
1188 else
1189 s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"'
1190 INTERP._eval(format('global %s; set %s %s', @id, @id, s))
1191 end
1192 end
1193
1194 def wait
1195 INTERP._eval("tkwait variable #{@id}")
1196 end
1197
1198 def id
1199 @id
1200 end
1201
1202 def value
1203 begin
1204 INTERP._eval(format('global %s; set %s', @id, @id))
1205 rescue
1206 if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
1207 fail
1208 else
1209 Hash[*tk_split_simplelist(INTERP._eval(format('global %s; array get %s',
1210 @id, @id)))]
1211 end
1212 end
1213 end
1214
1215 def value=(val)
1216 begin
1217 s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"'
1218 INTERP._eval(format('global %s; set %s %s', @id, @id, s))
1219 rescue
1220 if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
1221 fail
1222 else
1223 if val == []
1224 INTERP._eval(format('global %s; unset %s; set %s(0) 0; unset %s(0)',
1225 @id, @id, @id, @id))
1226 elsif val.kind_of?(Array)
1227 a = []
1228 val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
1229 s = '"' + a.join(" ").gsub(/[][$"]/, '\\\\\&') + '"'
1230 INTERP._eval(format('global %s; unset %s; array set %s %s',
1231 @id, @id, @id, s))
1232 elsif val.kind_of?(Hash)
1233 s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
1234 .gsub(/[][$"]/, '\\\\\&') + '"'
1235 INTERP._eval(format('global %s; unset %s; array set %s %s',
1236 @id, @id, @id, s))
1237 else
1238 fail
1239 end
1240 end
1241 end
1242 end
1243
1244 def [](index)
1245 INTERP._eval(format('global %s; set %s(%s)',
1246 @id, @id, _get_eval_string(index)))
1247 end
1248
1249 def []=(index,val)
1250 INTERP._eval(format('global %s; set %s(%s) %s', @id, @id,
1251 _get_eval_string(index), _get_eval_string(val)))
1252 end
1253
1254 def to_i
1255 number(value).to_i
1256 end
1257
1258 def to_f
1259 number(value).to_f
1260 end
1261
1262 def to_s
1263 string(value).to_s
1264 end
1265
1266 def inspect
1267 format "#<TkVariable: %s>", @id
1268 end
1269
1270 def ==(other)
1271 case other
1272 when TkVariable
1273 self.equal(self)
1274 when String
1275 self.to_s == other
1276 when Integer
1277 self.to_i == other
1278 when Float
1279 self.to_f == other
1280 when Array
1281 self.to_a == other
1282 else
1283 false
1284 end
1285 end
1286
1287 def to_a
1288 list(value)
1289 end
1290
1291 def to_eval
1292 @id
1293 end
1294
1295 def unset(elem=nil)
1296 if elem
1297 INTERP._eval(format('global %s; unset %s(%s)',
1298 @id, @id, tk_tcl2ruby(elem)))
1299 else
1300 INTERP._eval(format('global %s; unset %s', @id, @id))
1301 end
1302 end
1303 alias remove unset
1304
1305 def trace_callback(elem, op)
1306 if @trace_var.kind_of? Array
1307 @trace_var.each{|m,e| e.call(self,elem,op) if m.index(op)}
1308 end
1309 if elem.kind_of? String
1310 if @trace_elem[elem].kind_of? Array
1311 @trace_elem[elem].each{|m,e| e.call(self,elem,op) if m.index(op)}
1312 end
1313 end
1314 end
1315
1316 def trace(opts, cmd)
1317 @trace_var = [] if @trace_var == nil
1318 opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('')
1319 @trace_var.unshift([opts,cmd])
1320 if @trace_opts == nil
1321 TkVar_CB_TBL[@id] = self
1322 @trace_opts = opts
1323 Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var')
1324 else
1325 newopts = @trace_opts.dup
1326 opts.each_byte{|c| newopts += c.chr unless newopts.index(c)}
1327 if newopts != @trace_opts
1328 Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var')
1329 @trace_opts.replace(newopts)
1330 Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var')
1331 end
1332 end
1333 end
1334
1335 def trace_element(elem, opts, cmd)
1336 @trace_elem = {} if @trace_elem == nil
1337 @trace_elem[elem] = [] if @trace_elem[elem] == nil
1338 opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('')
1339 @trace_elem[elem].unshift([opts,cmd])
1340 if @trace_opts == nil
1341 TkVar_CB_TBL[@id] = self
1342 @trace_opts = opts
1343 Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var')
1344 else
1345 newopts = @trace_opts.dup
1346 opts.each_byte{|c| newopts += c.chr unless newopts.index(c)}
1347 if newopts != @trace_opts
1348 Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var')
1349 @trace_opts.replace(newopts)
1350 Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var')
1351 end
1352 end
1353 end
1354
1355 def trace_vinfo
1356 return [] unless @trace_var
1357 @trace_var.dup
1358 end
1359 def trace_vinfo_for_element(elem)
1360 return [] unless @trace_elem
1361 return [] unless @trace_elem[elem]
1362 @trace_elem[elem].dup
1363 end
1364
1365 def trace_vdelete(opts,cmd)
1366 return unless @trace_var.kind_of? Array
1367 opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('')
1368 idx = -1
1369 newopts = ''
1370 @trace_var.each_with_index{|e,i|
1371 if idx < 0 && e[0] == opts && e[1] == cmd
1372 idx = i
1373 next
1374 end
1375 e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
1376 }
1377 if idx >= 0
1378 @trace_var.delete_at(idx)
1379 else
1380 return
1381 end
1382
1383 @trace_elem.each{|elem|
1384 @trace_elem[elem].each{|e|
1385 e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
1386 }
1387 }
1388
1389 newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('')
1390 if newopts != @trace_opts
1391 Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var')
1392 @trace_opts.replace(newopts)
1393 if @trace_opts != ''
1394 Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var')
1395 end
1396 end
1397 end
1398
1399 def trace_vdelete_for_element(elem,opts,cmd)
1400 return unless @trace_elem.kind_of? Hash
1401 return unless @trace_elem[elem].kind_of? Array
1402 opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('')
1403 idx = -1
1404 @trace_elem[elem].each_with_index{|e,i|
1405 if idx < 0 && e[0] == opts && e[1] == cmd
1406 idx = i
1407 next
1408 end
1409 }
1410 if idx >= 0
1411 @trace_elem[elem].delete_at(idx)
1412 else
1413 return
1414 end
1415
1416 newopts = ''
1417 @trace_var.each{|e|
1418 e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
1419 }
1420 @trace_elem.each{|elem|
1421 @trace_elem[elem].each{|e|
1422 e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
1423 }
1424 }
1425
1426 newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('')
1427 if newopts != @trace_opts
1428 Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var')
1429 @trace_opts.replace(newopts)
1430 if @trace_opts != ''
1431 Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var')
1432 end
1433 end
1434 end
1435 end
1436
1437 class TkVarAccess<TkVariable
1438 def initialize(varname, val=nil)
1439 @id = varname
1440 if val
1441 s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"' #"
1442 INTERP._eval(format('global %s; set %s %s', @id, @id, s))
1443 end
1444 end
1445 end
1446
1447 module Tk
1448 begin
1449 auto_path = INTERP._invoke('set', 'auto_path')
1450 rescue
1451 begin
1452 auto_path = INTERP._invoke('set', 'env(TCLLIBPATH)')
1453 rescue
1454 auto_path = Tk::LIBRARY
1455 end
1456 end
1457 AUTO_PATH = TkVarAccess.new('auto_path', auto_path)
1458
1459 TCL_PACKAGE_PATH = TkVarAccess.new('tcl_pkgPath')
1460 end
1461
1462 module TkSelection
1463 include Tk
1464 extend Tk
1465 def clear(win=Tk.root)
1466 tk_call 'selection', 'clear', win.path
1467 end
1468 def get(type=None)
1469 tk_call 'selection', 'get', type
1470 end
1471 def TkSelection.handle(win, func, type=None, format=None)
1472 tk_call 'selection', 'handle', win.path, func, type, format
1473 end
1474 def handle(func, type=None, format=None)
1475 TkSelection.handle self, func, type, format
1476 end
1477 def TkSelection.own(win=None, func=None)
1478 window(tk_call('selection', 'own', win, func))
1479 end
1480 def own(func=None)
1481 TkSelection.own self, func
1482 end
1483
1484 module_function :clear, :get
1485 end
1486
1487 module TkKinput
1488 include Tk
1489 extend Tk
1490
1491 def TkKinput.start(window, style=None)
1492 tk_call 'kinput_start', window.path, style
1493 end
1494 def kinput_start(style=None)
1495 TkKinput.start(self, style)
1496 end
1497
1498 def TkKinput.send_spot(window)
1499 tk_call 'kinput_send_spot', window.path
1500 end
1501 def kinput_send_spot
1502 TkKinput.send_spot(self)
1503 end
1504
1505 def TkKinput.input_start(window, keys=nil)
1506 tk_call 'kanjiInput', 'start', window.path, *hash_kv(keys)
1507 end
1508 def kanji_input_start(keys=nil)
1509 TkKinput.input_start(self, keys)
1510 end
1511
1512 def TkKinput.attribute_config(window, slot, value=None)
1513 if slot.kind_of? Hash
1514 tk_call 'kanjiInput', 'attribute', window.path, *hash_kv(slot)
1515 else
1516 tk_call 'kanjiInput', 'attribute', window.path, "-#{slot}", value
1517 end
1518 end
1519 def kinput_attribute_config(slot, value=None)
1520 TkKinput.attribute_config(self, slot, value)
1521 end
1522
1523 def TkKinput.attribute_info(window, slot=nil)
1524 if slot
1525 conf = tk_split_list(tk_call('kanjiInput', 'attribute',
1526 window.path, "-#{slot}"))
1527 conf[0] = conf[0][1..-1]
1528 conf
1529 else
1530 tk_split_list(tk_call('kanjiInput', 'attribute',
1531 window.path)).collect{|conf|
1532 conf[0] = conf[0][1..-1]
1533 conf
1534 }
1535 end
1536 end
1537 def kinput_attribute_info(slot=nil)
1538 TkKinput.attribute_info(self, slot)
1539 end
1540
1541 def TkKinput.input_end(window)
1542 tk_call 'kanjiInput', 'end', window.path
1543 end
1544 def kanji_input_end
1545 TkKinput.input_end(self)
1546 end
1547 end
1548
1549 module TkXIM
1550 include Tk
1551 extend Tk
1552
1553 def TkXIM.useinputmethods(window=nil, value=nil)
1554 if window
1555 if value
1556 tk_call 'tk', 'useinputmethods', '-displayof', window.path, value
1557 else
1558 tk_call 'tk', 'useinputmethods', '-displayof', window.path
1559 end
1560 else
1561 if value
1562 tk_call 'tk', 'useinputmethods', value
1563 else
1564 tk_call 'tk', 'useinputmethods'
1565 end
1566 end
1567 end
1568
1569 def TkXIM.configure(window, slot, value=None)
1570 begin
1571 if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK
1572 if slot.kind_of? Hash
1573 tk_call 'imconfigure', window.path, *hash_kv(slot)
1574 else
1575 tk_call 'imconfigure', window.path, "-#{slot}", value
1576 end
1577 end
1578 rescue
1579 end
1580 end
1581
1582 def TkXIM.configinfo(window, slot=nil)
1583 begin
1584 if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK
1585 if slot
1586 conf = tk_split_list(tk_call('imconfigure', window.path, "-#{slot}"))
1587 conf[0] = conf[0][1..-1]
1588 conf
1589 else
1590 tk_split_list(tk_call('imconfigure', window.path)).collect{|conf|
1591 conf[0] = conf[0][1..-1]
1592 conf
1593 }
1594 end
1595 else
1596 []
1597 end
1598 rescue
1599 []
1600 end
1601 end
1602
1603 def useinputmethods(value=nil)
1604 TkXIM.useinputmethods(self, value)
1605 end
1606
1607 def imconfigure(window, slot, value=None)
1608 TkXIM.configinfo(window, slot, value)
1609 end
1610
1611 def imconfiginfo(slot=nil)
1612 TkXIM.configinfo(window, slot)
1613 end
1614 end
1615
1616 module TkWinfo
1617 include Tk
1618 extend Tk
1619 def TkWinfo.atom(name)
1620 number(tk_call('winfo', 'atom', name))
1621 end
1622 def winfo_atom(name)
1623 TkWinfo.atom name
1624 end
1625 def TkWinfo.atomname(id)
1626 tk_call 'winfo', 'atomname', id
1627 end
1628 def winfo_atomname(id)
1629 TkWinfo.atomname id
1630 end
1631 def TkWinfo.cells(window)
1632 number(tk_call('winfo', 'cells', window.path))
1633 end
1634 def winfo_cells
1635 TkWinfo.cells self
1636 end
1637 def TkWinfo.children(window)
1638 c = tk_call('winfo', 'children', window.path)
1639 list(c)
1640 end
1641 def winfo_children
1642 TkWinfo.children self
1643 end
1644 def TkWinfo.classname(window)
1645 tk_call 'winfo', 'class', window.path
1646 end
1647 def winfo_classname
1648 TkWinfo.classname self
1649 end
1650 def TkWinfo.colormapfull(window)
1651 bool(tk_call('winfo', 'colormapfull', window.path))
1652 end
1653 def winfo_colormapfull
1654 TkWinfo.colormapfull self
1655 end
1656 def TkWinfo.containing(rootX, rootY)
1657 path = tk_call('winfo', 'containing', rootX, rootY)
1658 window(path)
1659 end
1660 def winfo_containing(x, y)
1661 TkWinfo.containing x, y
1662 end
1663 def TkWinfo.depth(window)
1664 number(tk_call('winfo', 'depth', window.path))
1665 end
1666 def winfo_depth
1667 TkWinfo.depth self
1668 end
1669 def TkWinfo.exist?(window)
1670 bool(tk_call('winfo', 'exists', window.path))
1671 end
1672 def winfo_exist?
1673 TkWinfo.exist? self
1674 end
1675 def TkWinfo.fpixels(window, number)
1676 number(tk_call('winfo', 'fpixels', window.path, number))
1677 end
1678 def winfo_fpixels(number)
1679 TkWinfo.fpixels self, number
1680 end
1681 def TkWinfo.geometry(window)
1682 tk_call('winfo', 'geometry', window.path)
1683 end
1684 def winfo_geometry
1685 TkWinfo.geometry self
1686 end
1687 def TkWinfo.height(window)
1688 number(tk_call('winfo', 'height', window.path))
1689 end
1690 def winfo_height
1691 TkWinfo.height self
1692 end
1693 def TkWinfo.id(window)
1694 tk_call('winfo', 'id', window.path)
1695 end
1696 def winfo_id
1697 TkWinfo.id self
1698 end
1699 def TkWinfo.interps(window=nil)
1700 if window
1701 tk_split_simplelist(tk_call('winfo', 'interps',
1702 '-displayof', window.path))
1703 else
1704 tk_split_simplelist(tk_call('winfo', 'interps'))
1705 end
1706 end
1707 def winfo_interps
1708 TkWinfo.interps self
1709 end
1710 def TkWinfo.mapped?(window)
1711 bool(tk_call('winfo', 'ismapped', window.path))
1712 end
1713 def winfo_mapped?
1714 TkWinfo.mapped? self
1715 end
1716 def TkWinfo.manager(window)
1717 tk_call('winfo', 'manager', window.path)
1718 end
1719 def winfo_manager
1720 TkWinfo.manager self
1721 end
1722 def TkWinfo.appname(window)
1723 tk_call('winfo', 'name', window.path)
1724 end
1725 def winfo_appname
1726 TkWinfo.appname self
1727 end
1728 def TkWinfo.parent(window)
1729 window(tk_call('winfo', 'parent', window.path))
1730 end
1731 def winfo_parent
1732 TkWinfo.parent self
1733 end
1734 def TkWinfo.widget(id)
1735 window(tk_call('winfo', 'pathname', id))
1736 end
1737 def winfo_widget(id)
1738 TkWinfo.widget id
1739 end
1740 def TkWinfo.pixels(window, number)
1741 number(tk_call('winfo', 'pixels', window.path, number))
1742 end
1743 def winfo_pixels(number)
1744 TkWinfo.pixels self, number
1745 end
1746 def TkWinfo.reqheight(window)
1747 number(tk_call('winfo', 'reqheight', window.path))
1748 end
1749 def winfo_reqheight
1750 TkWinfo.reqheight self
1751 end
1752 def TkWinfo.reqwidth(window)
1753 number(tk_call('winfo', 'reqwidth', window.path))
1754 end
1755 def winfo_reqwidth
1756 TkWinfo.reqwidth self
1757 end
1758 def TkWinfo.rgb(window, color)
1759 list(tk_call('winfo', 'rgb', window.path, color))
1760 end
1761 def winfo_rgb(color)
1762 TkWinfo.rgb self, color
1763 end
1764 def TkWinfo.rootx(window)
1765 number(tk_call('winfo', 'rootx', window.path))
1766 end
1767 def winfo_rootx
1768 TkWinfo.rootx self
1769 end
1770 def TkWinfo.rooty(window)
1771 number(tk_call('winfo', 'rooty', window.path))
1772 end
1773 def winfo_rooty
1774 TkWinfo.rooty self
1775 end
1776 def TkWinfo.screen(window)
1777 tk_call 'winfo', 'screen', window.path
1778 end
1779 def winfo_screen
1780 TkWinfo.screen self
1781 end
1782 def TkWinfo.screencells(window)
1783 number(tk_call('winfo', 'screencells', window.path))
1784 end
1785 def winfo_screencells
1786 TkWinfo.screencells self
1787 end
1788 def TkWinfo.screendepth(window)
1789 number(tk_call('winfo', 'screendepth', window.path))
1790 end
1791 def winfo_screendepth
1792 TkWinfo.screendepth self
1793 end
1794 def TkWinfo.screenheight (window)
1795 number(tk_call('winfo', 'screenheight', window.path))
1796 end
1797 def winfo_screenheight
1798 TkWinfo.screenheight self
1799 end
1800 def TkWinfo.screenmmheight(window)
1801 number(tk_call('winfo', 'screenmmheight', window.path))
1802 end
1803 def winfo_screenmmheight
1804 TkWinfo.screenmmheight self
1805 end
1806 def TkWinfo.screenmmwidth(window)
1807 number(tk_call('winfo', 'screenmmwidth', window.path))
1808 end
1809 def winfo_screenmmwidth
1810 TkWinfo.screenmmwidth self
1811 end
1812 def TkWinfo.screenvisual(window)
1813 tk_call 'winfo', 'screenvisual', window.path
1814 end
1815 def winfo_screenvisual
1816 TkWinfo.screenvisual self
1817 end
1818 def TkWinfo.screenwidth(window)
1819 number(tk_call('winfo', 'screenwidth', window.path))
1820 end
1821 def winfo_screenwidth
1822 TkWinfo.screenwidth self
1823 end
1824 def TkWinfo.server(window)
1825 tk_call 'winfo', 'server', window.path
1826 end
1827 def winfo_server
1828 TkWinfo.server self
1829 end
1830 def TkWinfo.toplevel(window)
1831 window(tk_call('winfo', 'toplevel', window.path))
1832 end
1833 def winfo_toplevel
1834 TkWinfo.toplevel self
1835 end
1836 def TkWinfo.visual(window)
1837 tk_call 'winfo', 'visual', window.path
1838 end
1839 def winfo_visual
1840 TkWinfo.visual self
1841 end
1842 def TkWinfo.visualid(window)
1843 tk_call 'winfo', 'visualid', window.path
1844 end
1845 def winfo_visualid
1846 TkWinfo.visualid self
1847 end
1848 def TkWinfo.visualsavailable(window, includeids=false)
1849 if includeids
1850 v = tk_call('winfo', 'visualsavailable', window.path, "includeids")
1851 else
1852 v = tk_call('winfo', 'visualsavailable', window.path)
1853 end
1854 list(v)
1855 end
1856 def winfo_visualsavailable(includeids=false)
1857 TkWinfo.visualsavailable self, includeids
1858 end
1859 def TkWinfo.vrootheight(window)
1860 number(tk_call('winfo', 'vrootheight', window.path))
1861 end
1862 def winfo_vrootheight
1863 TkWinfo.vrootheight self
1864 end
1865 def TkWinfo.vrootwidth(window)
1866 number(tk_call('winfo', 'vrootwidth', window.path))
1867 end
1868 def winfo_vrootwidth
1869 TkWinfo.vrootwidth self
1870 end
1871 def TkWinfo.vrootx(window)
1872 number(tk_call('winfo', 'vrootx', window.path))
1873 end
1874 def winfo_vrootx
1875 TkWinfo.vrootx self
1876 end
1877 def TkWinfo.vrooty(window)
1878 number(tk_call('winfo', 'vrooty', window.path))
1879 end
1880 def winfo_vrooty
1881 TkWinfo.vrooty self
1882 end
1883 def TkWinfo.width(window)
1884 number(tk_call('winfo', 'width', window.path))
1885 end
1886 def winfo_width
1887 TkWinfo.width self
1888 end
1889 def TkWinfo.x(window)
1890 number(tk_call('winfo', 'x', window.path))
1891 end
1892 def winfo_x
1893 TkWinfo.x self
1894 end
1895 def TkWinfo.y(window)
1896 number(tk_call('winfo', 'y', window.path))
1897 end
1898 def winfo_y
1899 TkWinfo.y self
1900 end
1901 def TkWinfo.viewable(window)
1902 bool(tk_call('winfo', 'viewable', window.path))
1903 end
1904 def winfo_viewable
1905 TkWinfo.viewable self
1906 end
1907 def TkWinfo.pointerx(window)
1908 number(tk_call('winfo', 'pointerx', window.path))
1909 end
1910 def winfo_pointerx
1911 TkWinfo.pointerx self
1912 end
1913 def TkWinfo.pointery(window)
1914 number(tk_call('winfo', 'pointery', window.path))
1915 end
1916 def winfo_pointery
1917 TkWinfo.pointery self
1918 end
1919 def TkWinfo.pointerxy(window)
1920 list(tk_call('winfo', 'pointerxy', window.path))
1921 end
1922 def winfo_pointerxy
1923 TkWinfo.pointerxy self
1924 end
1925 end
1926
1927 module TkPack
1928 include Tk
1929 extend Tk
1930 def configure(win, *args)
1931 if args[-1].kind_of?(Hash)
1932 keys = args.pop
1933 end
1934 wins = [win.epath]
1935 for i in args
1936 wins.push i.epath
1937 end
1938 tk_call "pack", 'configure', *(wins+hash_kv(keys))
1939 end
1940
1941 def forget(*args)
1942 tk_call 'pack', 'forget' *args
1943 end
1944
1945 def info(slave)
1946 ilist = list(tk_call('pack', 'info', slave.epath))
1947 info = {}
1948 while key = ilist.shift
1949 info[key[1..-1]] = ilist.shift
1950 end
1951 return info
1952 end
1953
1954 def propagate(master, bool=None)
1955 if bool == None
1956 bool(tk_call('pack', 'propagate', master.epath))
1957 else
1958 tk_call('pack', 'propagate', master.epath, bool)
1959 end
1960 end
1961
1962 def slaves(master)
1963 list(tk_call('pack', 'slaves', master.epath))
1964 end
1965
1966 module_function :configure, :forget, :info, :propagate, :slaves
1967 end
1968
1969 module TkGrid
1970 include Tk
1971 extend Tk
1972
1973 def bbox(*args)
1974 list(tk_call('grid', 'bbox', *args))
1975 end
1976
1977 def configure(widget, *args)
1978 if args[-1].kind_of?(Hash)
1979 keys = args.pop
1980 end
1981 wins = [widget.epath]
1982 for i in args
1983 wins.push i.epath
1984 end
1985 tk_call "grid", 'configure', *(wins+hash_kv(keys))
1986 end
1987
1988 def columnconfigure(master, index, args)
1989 tk_call "grid", 'columnconfigure', master, index, *hash_kv(args)
1990 end
1991
1992 def rowconfigure(master, index, args)
1993 tk_call "grid", 'rowconfigure', master, index, *hash_kv(args)
1994 end
1995
1996 def columnconfiginfo(master, index, slot=nil)
1997 if slot
1998 tk_call 'grid', 'columnconfigure', master, index, "-#{slot}"
1999 else
2000 ilist = list(tk_call('grid', 'columnconfigure', master, index))
2001 info = {}
2002 while key = ilist.shift
2003 info[key[1..-1]] = ilist.shift
2004 end
2005 info
2006 end
2007 end
2008
2009 def rowconfiginfo(master, index, slot=nil)
2010 if slot
2011 tk_call 'grid', 'rowconfigure', master, index, "-#{slot}"
2012 else
2013 ilist = list(tk_call('grid', 'rowconfigure', master, index))
2014 info = {}
2015 while key = ilist.shift
2016 info[key[1..-1]] = ilist.shift
2017 end
2018 info
2019 end
2020 end
2021
2022 def add(widget, *args)
2023 configure(widget, *args)
2024 end
2025
2026 def forget(*args)
2027 tk_call 'grid', 'forget', *args
2028 end
2029
2030 def info(slave)
2031 list(tk_call('grid', 'info', slave))
2032 end
2033
2034 def location(master, x, y)
2035 list(tk_call('grid', 'location', master, x, y))
2036 end
2037
2038 def propagate(master, bool=None)
2039 if bool == None
2040 bool(tk_call('grid', 'propagate', master.epath))
2041 else
2042 tk_call('grid', 'propagate', master.epath, bool)
2043 end
2044 end
2045
2046 def remove(*args)
2047 tk_call 'grid', 'remove', *args
2048 end
2049
2050 def size(master)
2051 tk_call 'grid', 'size', master
2052 end
2053
2054 def slaves(master, args)
2055 list(tk_call('grid', 'slaves', master, *hash_kv(args)))
2056 end
2057
2058 module_function :bbox, :forget, :propagate, :info
2059 module_function :remove, :size, :slaves, :location
2060 module_function :configure, :columnconfigure, :rowconfigure
2061 module_function :columnconfiginfo, :rowconfiginfo
2062 end
2063
2064 module TkPlace
2065 include Tk
2066 extend Tk
2067
2068 def configure(win, slot, value=None)
2069 if slot.kind_of? Hash
2070 tk_call 'place', 'configure', win.epath, *hash_kv(slot)
2071 else
2072 tk_call 'place', 'configure', win.epath, "-#{slot}", value
2073 end
2074 end
2075
2076 def configinfo(win, slot = nil)
2077 # for >= Tk8.4a2 ?
2078 if slot
2079 conf = tk_split_list(tk_call('place', 'configure',
2080 win.epath, "-#{slot}") )
2081 conf[0] = conf[0][1..-1]
2082 conf
2083 else
2084 tk_split_simplelist(tk_call('place', 'configure',
2085 win.epath)).collect{|conflist|
2086 conf = tk_split_simplelist(conflist)
2087 conf[0] = conf[0][1..-1]
2088 conf
2089 }
2090 end
2091 end
2092
2093 def forget(win)
2094 tk_call 'place', 'forget', win
2095 end
2096
2097 def info(win)
2098 ilist = list(tk_call('place', 'info', win.epath))
2099 info = {}
2100 while key = ilist.shift
2101 info[key[1..-1]] = ilist.shift
2102 end
2103 return info
2104 end
2105
2106 def slaves(master)
2107 list(tk_call('place', 'slaves', master.epath))
2108 end
2109
2110 module_function :configure, :configinfo, :forget, :info, :slaves
2111 end
2112
2113 module TkOption
2114 include Tk
2115 extend Tk
2116 def add pat, value, pri=None
2117 tk_call 'option', 'add', pat, value, pri
2118 end
2119 def clear
2120 tk_call 'option', 'clear'
2121 end
2122 def get win, name, klass
2123 tk_call('option', 'get', win ,name, klass).taint
2124 end
2125 def readfile file, pri=None
2126 tk_call 'option', 'readfile', file, pri
2127 end
2128 module_function :add, :clear, :get, :readfile
2129
2130 # support procs on the resource database
2131 @@resource_proc_class = Class.new
2132 class << @@resource_proc_class
2133 private :new
2134
2135 CARRIER = '.'.freeze
2136 METHOD_TBL = {}
2137 ADD_METHOD = false
2138 SAFE_MODE = 4
2139
2140 def __check_proc_string__(str)
2141 # If you want to check the proc_string, do it in this method.
2142 str
2143 end
2144
2145 def method_missing(id, *args)
2146 res_proc = self::METHOD_TBL[id]
2147 unless res_proc.kind_of? Proc
2148 if id == :new || (!self::METHOD_TBL.has_key?(id) && !self::ADD_METHOD)
2149 raise NoMethodError,
2150 "not support resource-proc '#{id.id2name}' for #{self.name}"
2151 end
2152 proc_str = TkOption.get(self::CARRIER, id.id2name, '')
2153 proc_str = '{' + proc_str + '}' unless /\A\{.*\}\Z/ =~ proc_str
2154 proc_str = __check_proc_string__(proc_str)
2155 res_proc = eval 'Proc.new' + proc_str
2156 self::METHOD_TBL[id] = res_proc
2157 end
2158 proc{
2159 $SAFE = self::SAFE_MODE
2160 res_proc.call(*args)
2161 }.call
2162 end
2163
2164 private :__check_proc_string__, :method_missing
2165 end
2166
2167 def new_proc_class(klass, func, safe = 4, add = false, parent = nil)
2168 klass = klass.to_s if klass.kind_of? Symbol
2169 unless (?A..?Z) === klass[0]
2170 fail ArgumentError, "bad string '#{klass}' for class name"
2171 end
2172 unless func.kind_of? Array
2173 fail ArgumentError, "method-list must be Array"
2174 end
2175 func_str = func.join(' ')
2176 if parent == nil
2177 install_win(parent)
2178 elsif parent <= @@resource_proc_class
2179 install_win(parent::CARRIER)
2180 else
2181 fail ArgumentError, "parent must be Resource-Proc class"
2182 end
2183 carrier = Tk.tk_call('frame', @path, '-class', klass)
2184
2185 body = <<-"EOD"
2186 class #{klass} < TkOption.module_eval('@@resource_proc_class')
2187 CARRIER = '#{carrier}'.freeze
2188 METHOD_TBL = {}
2189 ADD_METHOD = #{add}
2190 SAFE_MODE = #{safe}
2191 %w(#{func_str}).each{|f| METHOD_TBL[f.intern] = nil }
2192 end
2193 EOD
2194
2195 if parent.kind_of?(Class) && parent <= @@resource_proc_class
2196 parent.class_eval body
2197 eval parent.name + '::' + klass
2198 else
2199 eval body
2200 eval 'TkOption::' + klass
2201 end
2202 end
2203 module_function :new_proc_class
2204 end
2205
2206 module TkTreatFont
2207 def font_configinfo
2208 ret = TkFont.used_on(self.path)
2209 if ret == nil
2210 ret = TkFont.init_widget_font(self.path, self.path, 'configure')
2211 end
2212 ret
2213 end
2214 alias fontobj font_configinfo
2215
2216 def font_configure(slot)
2217 slot = _symbolkey2str(slot)
2218 if (fnt = slot.delete('font'))
2219 if fnt.kind_of? TkFont
2220 return fnt.call_font_configure(self.path, self.path,'configure',slot)
2221 else
2222 latinfont_configure(fnt) if fnt
2223 end
2224 end
2225 if (ltn = slot.delete('latinfont'))
2226 latinfont_configure(ltn) if ltn
2227 end
2228 if (ltn = slot.delete('asciifont'))
2229 latinfont_configure(ltn) if ltn
2230 end
2231 if (knj = slot.delete('kanjifont'))
2232 kanjifont_configure(knj) if knj
2233 end
2234
2235 tk_call(self.path, 'configure', *hash_kv(slot)) if slot != {}
2236 self
2237 end
2238
2239 def latinfont_configure(ltn, keys=nil)
2240 fobj = fontobj
2241 if ltn.kind_of? TkFont
2242 conf = {}
2243 ltn.latin_configinfo.each{|key,val| conf[key] = val}
2244 if keys
2245 fobj.latin_configure(conf.update(keys))
2246 else
2247 fobj.latin_configure(conf)
2248 end
2249 else
2250 fobj.latin_replace(ltn)
2251 end
2252 end
2253 alias asciifont_configure latinfont_configure
2254
2255 def kanjifont_configure(knj, keys=nil)
2256 fobj = fontobj
2257 if knj.kind_of? TkFont
2258 conf = {}
2259 knj.kanji_configinfo.each{|key,val| conf[key] = val}
2260 if keys
2261 fobj.kanji_configure(conf.update(keys))
2262 else
2263 fobj.kanji_configure(cond)
2264 end
2265 else
2266 fobj.kanji_replace(knj)
2267 end
2268 end
2269
2270 def font_copy(window, tag=nil)
2271 if tag
2272 window.tagfontobj(tag).configinfo.each{|key,value|
2273 fontobj.configure(key,value)
2274 }
2275 fontobj.replace(window.tagfontobj(tag).latin_font,
2276 window.tagfontobj(tag).kanji_font)
2277 else
2278 window.fontobj.configinfo.each{|key,value|
2279 fontobj.configure(key,value)
2280 }
2281 fontobj.replace(window.fontobj.latin_font, window.fontobj.kanji_font)
2282 end
2283 end
2284
2285 def latinfont_copy(window, tag=nil)
2286 if tag
2287 fontobj.latin_replace(window.tagfontobj(tag).latin_font)
2288 else
2289 fontobj.latin_replace(window.fontobj.latin_font)
2290 end
2291 end
2292 alias asciifont_copy latinfont_copy
2293
2294 def kanjifont_copy(window, tag=nil)
2295 if tag
2296 fontobj.kanji_replace(window.tagfontobj(tag).kanji_font)
2297 else
2298 fontobj.kanji_replace(window.fontobj.kanji_font)
2299 end
2300 end
2301 end
2302
2303 module TkTreatItemFont
2304 def __conf_cmd(idx)
2305 raise NotImplementError, "need to define `__conf_cmd'"
2306 end
2307 def __item_pathname(tagOrId)
2308 raise NotImplementError, "need to define `__item_pathname'"
2309 end
2310 private :__conf_cmd, :__item_pathname
2311
2312 def tagfont_configinfo(tagOrId)
2313 pathname = __item_pathname(tagOrId)
2314 ret = TkFont.used_on(pathname)
2315 if ret == nil
2316 ret = TkFont.init_widget_font(pathname, self.path,
2317 __conf_cmd(0), __conf_cmd(1), tagOrId)
2318 end
2319 ret
2320 end
2321 alias tagfontobj tagfont_configinfo
2322
2323 def tagfont_configure(tagOrId, slot)
2324 pathname = __item_pathname(tagOrId)
2325 slot = _symbolkey2str(slot)
2326 if (fnt = slot.delete('font'))
2327 if fnt.kind_of? TkFont
2328 return fnt.call_font_configure(pathname, self.path,
2329 __conf_cmd(0), __conf_cmd(1),
2330 tagOrId, slot)
2331 else
2332 latintagfont_configure(tagOrId, fnt) if fnt
2333 end
2334 end
2335 if (ltn = slot.delete('latinfont'))
2336 latintagfont_configure(tagOrId, ltn) if ltn
2337 end
2338 if (ltn = slot.delete('asciifont'))
2339 latintagfont_configure(tagOrId, ltn) if ltn
2340 end
2341 if (knj = slot.delete('kanjifont'))
2342 kanjitagfont_configure(tagOrId, knj) if knj
2343 end
2344
2345 tk_call(self.path, __conf_cmd(0), __conf_cmd(1),
2346 tagOrId, *hash_kv(slot)) if slot != {}
2347 self
2348 end
2349
2350 def latintagfont_configure(tagOrId, ltn, keys=nil)
2351 fobj = tagfontobj(tagOrId)
2352 if ltn.kind_of? TkFont
2353 conf = {}
2354 ltn.latin_configinfo.each{|key,val| conf[key] = val if val != []}
2355 if conf == {}
2356 fobj.latin_replace(ltn)
2357 fobj.latin_configure(keys) if keys
2358 elsif keys
2359 fobj.latin_configure(conf.update(keys))
2360 else
2361 fobj.latin_configure(conf)
2362 end
2363 else
2364 fobj.latin_replace(ltn)
2365 end
2366 end
2367 alias asciitagfont_configure latintagfont_configure
2368
2369 def kanjitagfont_configure(tagOrId, knj, keys=nil)
2370 fobj = tagfontobj(tagOrId)
2371 if knj.kind_of? TkFont
2372 conf = {}
2373 knj.kanji_configinfo.each{|key,val| conf[key] = val if val != []}
2374 if conf == {}
2375 fobj.kanji_replace(knj)
2376 fobj.kanji_configure(keys) if keys
2377 elsif keys
2378 fobj.kanji_configure(conf.update(keys))
2379 else
2380 fobj.kanji_configure(conf)
2381 end
2382 else
2383 fobj.kanji_replace(knj)
2384 end
2385 end
2386
2387 def tagfont_copy(tagOrId, window, wintag=nil)
2388 if wintag
2389 window.tagfontobj(wintag).configinfo.each{|key,value|
2390 tagfontobj(tagOrId).configure(key,value)
2391 }
2392 tagfontobj(tagOrId).replace(window.tagfontobj(wintag).latin_font,
2393 window.tagfontobj(wintag).kanji_font)
2394 else
2395 window.tagfont(wintag).configinfo.each{|key,value|
2396 tagfontobj(tagOrId).configure(key,value)
2397 }
2398 tagfontobj(tagOrId).replace(window.fontobj.latin_font,
2399 window.fontobj.kanji_font)
2400 end
2401 end
2402
2403 def latintagfont_copy(tagOrId, window, wintag=nil)
2404 if wintag
2405 tagfontobj(tagOrId).latin_replace(window.tagfontobj(wintag).latin_font)
2406 else
2407 tagfontobj(tagOrId).latin_replace(window.fontobj.latin_font)
2408 end
2409 end
2410 alias asciitagfont_copy latintagfont_copy
2411
2412 def kanjitagfont_copy(tagOrId, window, wintag=nil)
2413 if wintag
2414 tagfontobj(tagOrId).kanji_replace(window.tagfontobj(wintag).kanji_font)
2415 else
2416 tagfontobj(tagOrId).kanji_replace(window.fontobj.kanji_font)
2417 end
2418 end
2419 end
2420
2421 class TkObject<TkKernel
2422 include Tk
2423 include TkTreatFont
2424 include TkBindCore
2425
2426 def path
2427 return @path
2428 end
2429
2430 def epath
2431 return @path
2432 end
2433
2434 def to_eval
2435 @path
2436 end
2437
2438 def tk_send(cmd, *rest)
2439 tk_call path, cmd, *rest
2440 end
2441 private :tk_send
2442
2443 def method_missing(id, *args)
2444 name = id.id2name
2445 case args.length
2446 when 1
2447 configure name, args[0]
2448 when 0
2449 begin
2450 cget name
2451 rescue
2452 fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at
2453 end
2454 else
2455 fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at
2456 end
2457 end
2458
2459 def [](id)
2460 cget id
2461 end
2462
2463 def []=(id, val)
2464 configure id, val
2465 end
2466
2467 def cget(slot)
2468 case slot.to_s
2469 when 'text', 'label', 'show', 'data', 'file'
2470 tk_call path, 'cget', "-#{slot}"
2471 else
2472 tk_tcl2ruby tk_call(path, 'cget', "-#{slot}")
2473 end
2474 end
2475
2476 def configure(slot, value=None)
2477 if slot.kind_of? Hash
2478 if (slot['font'] || slot[:font] ||
2479 slot['kanjifont'] || slot[:kanjifont] ||
2480 slot['latinfont'] || slot[:latinfont] ||
2481 slot['asciifont'] || slot[:asciifont] )
2482 font_configure(slot)
2483 else
2484 tk_call path, 'configure', *hash_kv(slot)
2485 end
2486
2487 else
2488 if (slot == 'font' || slot == :font ||
2489 slot == 'kanjifont' || slot == :kanjifont ||
2490 slot == 'latinfont' || slot == :latinfont ||
2491 slot == 'asciifont' || slot == :asciifont )
2492 if value == None
2493 fontobj
2494 else
2495 font_configure({slot=>value})
2496 end
2497 else
2498 tk_call path, 'configure', "-#{slot}", value
2499 end
2500 end
2501 end
2502
2503 def configure_cmd(slot, value)
2504 configure slot, install_cmd(value)
2505 end
2506
2507 def configinfo(slot = nil)
2508 if slot == 'font' || slot == :font ||
2509 slot == 'kanjifont' || slot == :kanjifont
2510 fontobj
2511 else
2512 if slot
2513 case slot.to_s
2514 when 'text', 'label', 'show', 'data', 'file'
2515 conf = tk_split_simplelist(tk_send('configure', "-#{slot}") )
2516 else
2517 conf = tk_split_list(tk_send('configure', "-#{slot}") )
2518 end
2519 conf[0] = conf[0][1..-1]
2520 conf
2521 else
2522 ret = tk_split_simplelist(tk_send('configure') ).collect{|conflist|
2523 conf = tk_split_simplelist(conflist)
2524 conf[0] = conf[0][1..-1]
2525 case conf[0]
2526 when 'text', 'label', 'show', 'data', 'file'
2527 else
2528 if conf[3]
2529 if conf[3].index('{')
2530 conf[3] = tk_split_list(conf[3])
2531 else
2532 conf[3] = tk_tcl2ruby(conf[3])
2533 end
2534 end
2535 if conf[4]
2536 if conf[4].index('{')
2537 conf[4] = tk_split_list(conf[4])
2538 else
2539 conf[4] = tk_tcl2ruby(conf[4])
2540 end
2541 end
2542 end
2543 conf
2544 }
2545 fontconf = ret.assoc('font')
2546 if fontconf
2547 ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
2548 fontconf[4] = fontobj
2549 ret.push(fontconf)
2550 else
2551 ret
2552 end
2553 end
2554 end
2555 end
2556
2557 def event_generate(context, keys=nil)
2558 if keys
2559 tk_call('event', 'generate', path,
2560 "<#{tk_event_sequence(context)}>", *hash_kv(keys))
2561 else
2562 tk_call('event', 'generate', path, "<#{tk_event_sequence(context)}>")
2563 end
2564 end
2565
2566 def tk_trace_variable(v)
2567 unless v.kind_of?(TkVariable)
2568 fail ArgumentError, format("requires TkVariable given %s", v.type)
2569 end
2570 v
2571 end
2572 private :tk_trace_variable
2573
2574 def destroy
2575 tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if @var_id
2576 end
2577 end
2578
2579 class TkWindow<TkObject
2580 extend TkBindCore
2581
2582 def initialize(parent=nil, keys=nil)
2583 if parent.kind_of? Hash
2584 keys = _symbolkey2str(parent)
2585 keydup = true
2586 parent = keys.delete('parent')
2587 widgetname = keys.delete('widgetname')
2588 install_win(if parent then parent.path end, widgetname)
2589 elsif keys
2590 keys = _symbolkey2str(keys)
2591 widgetname = keys.delete('widgetname')
2592 install_win(if parent then parent.path end, widgetname)
2593 else
2594 install_win(if parent then parent.path end)
2595 end
2596 if self.method(:create_self).arity == 0
2597 p 'create_self has no arg' if $DEBUG
2598 create_self
2599 if keys
2600 # tk_call @path, 'configure', *hash_kv(keys)
2601 configure(keys)
2602 end
2603 else
2604 p 'create_self has args' if $DEBUG
2605 fontkeys = {}
2606 if keys
2607 ['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key|
2608 fontkeys[key] = keys.delete(key) if keys.key?(key)
2609 }
2610 end
2611 create_self(keys)
2612 font_configure(fontkeys) unless fontkeys.empty?
2613 end
2614 end
2615
2616 def create_self
2617 end
2618 private :create_self
2619
2620 def pack(keys = nil)
2621 tk_call 'pack', epath, *hash_kv(keys)
2622 self
2623 end
2624
2625 def unpack
2626 tk_call 'pack', 'forget', epath
2627 self
2628 end
2629 alias pack_forget unpack
2630
2631 def pack_config(slot, value=None)
2632 if slot.kind_of? Hash
2633 tk_call 'pack', 'configure', epath, *hash_kv(slot)
2634 else
2635 tk_call 'pack', 'configure', epath, "-#{slot}", value
2636 end
2637 end
2638
2639 def pack_info()
2640 ilist = list(tk_call('pack', 'info', epath))
2641 info = {}
2642 while key = ilist.shift
2643 info[key[1..-1]] = ilist.shift
2644 end
2645 return info
2646 end
2647
2648 def pack_propagate(mode = nil)
2649 if mode
2650 tk_call('pack', 'propagate', epath, mode)
2651 else
2652 bool(tk_call('pack', 'propagate', epath))
2653 end
2654 end
2655
2656 def pack_slaves()
2657 list(tk_call('pack', 'slaves', epath))
2658 end
2659
2660 def grid(keys = nil)
2661 tk_call 'grid', epath, *hash_kv(keys)
2662 self
2663 end
2664
2665 def ungrid
2666 tk_call 'grid', 'forget', epath
2667 self
2668 end
2669 alias grid_forget ungrid
2670
2671 def grid_bbox(*args)
2672 list(tk_call('grid', 'bbox', epath, *args))
2673 end
2674
2675 def grid_config(slot, value=None)
2676 if slot.kind_of? Hash
2677 tk_call 'grid', 'configure', epath, *hash_kv(slot)
2678 else
2679 tk_call 'grid', 'configure', epath, "-#{slot}", value
2680 end
2681 end
2682
2683 def grid_columnconfig(index, keys)
2684 tk_call('grid', 'columnconfigure', epath, index, *hash_kv(keys))
2685 end
2686
2687 def grid_rowconfig(index, keys)
2688 tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys))
2689 end
2690
2691 def grid_columnconfiginfo(index, slot=nil)
2692 if slot
2693 tk_call('grid', 'columnconfigure', epath, index, "-#{slot}")
2694 else
2695 ilist = list(tk_call('grid', 'columnconfigure', epath, index))
2696 info = {}
2697 while key = ilist.shift
2698 info[key[1..-1]] = ilist.shift
2699 end
2700 info
2701 end
2702 end
2703
2704 def grid_rowconfiginfo(index, slot=nil)
2705 if slot
2706 tk_call('grid', 'rowconfigure', epath, index, "-#{slot}")
2707 else
2708 ilist = list(tk_call('grid', 'rowconfigure', epath, index))
2709 info = {}
2710 while key = ilist.shift
2711 info[key[1..-1]] = ilist.shift
2712 end
2713 info
2714 end
2715 end
2716
2717 def grid_info()
2718 list(tk_call('grid', 'info', epath))
2719 end
2720
2721 def grid_location(x, y)
2722 list(tk_call('grid', 'location', epath, x, y))
2723 end
2724
2725 def grid_propagate(mode=nil)
2726 if mode
2727 tk_call('grid', 'propagate', epath, mode)
2728 else
2729 bool(tk_call('grid', 'propagate', epath))
2730 end
2731 end
2732
2733 def grid_remove()
2734 tk_call 'grid', 'remove', epath
2735 end
2736
2737 def grid_size()
2738 tk_call 'grid', 'size', epath
2739 end
2740
2741 def grid_slaves(args)
2742 list(tk_call('grid', 'slaves', epath, *hash_kv(args)))
2743 end
2744
2745 def place(keys = nil)
2746 tk_call 'place', epath, *hash_kv(keys)
2747 self
2748 end
2749
2750 def unplace
2751 tk_call 'place', 'forget', epath
2752 self
2753 end
2754 alias place_forget unplace
2755
2756 def place_config(slot, value=None)
2757 if slot.kind_of? Hash
2758 tk_call 'place', 'configure', epath, *hash_kv(slot)
2759 else
2760 tk_call 'place', 'configure', epath, "-#{slot}", value
2761 end
2762 end
2763
2764 def place_configinfo(slot = nil)
2765 # for >= Tk8.4a2 ?
2766 if slot
2767 conf = tk_split_list(tk_call('place', 'configure', epath, "-#{slot}") )
2768 conf[0] = conf[0][1..-1]
2769 conf
2770 else
2771 tk_split_simplelist(tk_call('place',
2772 'configure', epath)).collect{|conflist|
2773 conf = tk_split_simplelist(conflist)
2774 conf[0] = conf[0][1..-1]
2775 conf
2776 }
2777 end
2778 end
2779
2780 def place_info()
2781 ilist = list(tk_call('place', 'info', epath))
2782 info = {}
2783 while key = ilist.shift
2784 info[key[1..-1]] = ilist.shift
2785 end
2786 return info
2787 end
2788
2789 def place_slaves()
2790 list(tk_call('place', 'slaves', epath))
2791 end
2792
2793 def focus(force=false)
2794 if force
2795 tk_call 'focus', '-force', path
2796 else
2797 tk_call 'focus', path
2798 end
2799 self
2800 end
2801
2802 def grab(*args)
2803 if !args or args.length == 0
2804 tk_call 'grab', 'set', path
2805 elsif args.length == 1
2806 case args[0]
2807 when 'global', :global
2808 return(tk_call('grab', 'set', '-global', path))
2809 when 'release', :release
2810 return tk_call('grab', 'release', path)
2811 else
2812 val = tk_call('grab', args[0], path)
2813 end
2814 case args[0]
2815 when 'current', :current
2816 return window(val)
2817 when 'status', :status
2818 return val
2819 end
2820 else
2821 fail ArgumentError, 'wrong # of args'
2822 end
2823 end
2824
2825 def lower(below=None)
2826 tk_call 'lower', epath, below
2827 self
2828 end
2829 def raise(above=None)
2830 tk_call 'raise', epath, above
2831 self
2832 end
2833
2834 def command(cmd=Proc.new)
2835 configure_cmd 'command', cmd
2836 end
2837
2838 def colormodel model=None
2839 tk_call 'tk', 'colormodel', path, model
2840 self
2841 end
2842
2843 def destroy
2844 tk_call 'destroy', epath
2845 if @cmdtbl
2846 for id in @cmdtbl
2847 uninstall_cmd id
2848 end
2849 end
2850 uninstall_win
2851 end
2852
2853 def wait_visibility
2854 tk_call 'tkwait', 'visibility', path
2855 end
2856 alias wait wait_visibility
2857
2858 def wait_destroy
2859 tk_call 'tkwait', 'window', epath
2860 end
2861
2862 def bindtags(taglist=nil)
2863 if taglist
2864 fail ArgumentError unless taglist.kind_of? Array
2865 tk_call('bindtags', path, taglist)
2866 else
2867 list(tk_call('bindtags', path)).collect{|tag|
2868 if tag.kind_of?(String)
2869 if cls = WidgetClassNames[tag]
2870 cls
2871 elsif btag = TkBindTag.id2obj(tag)
2872 btag
2873 else
2874 tag
2875 end
2876 else
2877 tag
2878 end
2879 }
2880 end
2881 end
2882 end
2883
2884 class TkRoot<TkWindow
2885 include Wm
2886 ROOT = []
2887 def TkRoot.new
2888 return ROOT[0] if ROOT[0]
2889 new = super
2890 ROOT[0] = new
2891 Tk_WINDOWS["."] = new
2892 end
2893
2894 WidgetClassName = 'Tk'.freeze
2895 WidgetClassNames[WidgetClassName] = self
2896 def self.to_eval
2897 WidgetClassName
2898 end
2899
2900 def create_self
2901 @path = '.'
2902 end
2903 def path
2904 "."
2905 end
2906 end
2907
2908 class TkToplevel<TkWindow
2909 include Wm
2910
2911 WidgetClassName = 'Toplevel'.freeze
2912 WidgetClassNames[WidgetClassName] = self
2913 def self.to_eval
2914 WidgetClassName
2915 end
2916
2917 ################# old version
2918 # def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
2919 # if screen.kind_of? Hash
2920 # keys = screen.dup
2921 # else
2922 # @screen = screen
2923 # end
2924 # @classname = classname
2925 # if keys.kind_of? Hash
2926 # keys = keys.dup
2927 # @classname = keys.delete('classname') if keys.key?('classname')
2928 # @colormap = keys.delete('colormap') if keys.key?('colormap')
2929 # @container = keys.delete('container') if keys.key?('container')
2930 # @screen = keys.delete('screen') if keys.key?('screen')
2931 # @use = keys.delete('use') if keys.key?('use')
2932 # @visual = keys.delete('visual') if keys.key?('visual')
2933 # end
2934 # super(parent, keys)
2935 # end
2936 #
2937 # def create_self
2938 # s = []
2939 # s << "-class" << @classname if @classname
2940 # s << "-colormap" << @colormap if @colormap
2941 # s << "-container" << @container if @container
2942 # s << "-screen" << @screen if @screen
2943 # s << "-use" << @use if @use
2944 # s << "-visual" << @visual if @visual
2945 # tk_call 'toplevel', @path, *s
2946 # end
2947 #################
2948
2949 def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
2950 if parent.kind_of? Hash
2951 keys = _symbolkey2str(parent)
2952 @screen = keys['screen']
2953 @classname = keys['class']
2954 @colormap = keys['colormap']
2955 @container = keys['container']
2956 @screen = keys['screen']
2957 @use = keys['use']
2958 @visual = keys['visual']
2959 super(keys)
2960 return
2961 end
2962 if screen.kind_of? Hash
2963 keys = _symbolkey2str(screen)
2964 else
2965 @screen = screen
2966 end
2967 @classname = classname
2968 if keys.kind_of? Hash
2969 keys = _symbolkey2str(keys)
2970 if keys.key?(:classname) || keys.key?('classname')
2971 keys['class'] = keys.delete('classname')
2972 end
2973 @classname = keys['class']
2974 @colormap = keys['colormap']
2975 @container = keys['container']
2976 @screen = keys['screen']
2977 @use = keys['use']
2978 @visual = keys['visual']
2979 end
2980 super(parent, keys)
2981 end
2982
2983 def create_self(keys)
2984 if keys and keys != None
2985 tk_call 'toplevel', @path, *hash_kv(keys)
2986 else
2987 tk_call 'toplevel', @path
2988 end
2989 end
2990
2991 def specific_class
2992 @classname
2993 end
2994 end
2995
2996 class TkFrame<TkWindow
2997 WidgetClassName = 'Frame'.freeze
2998 WidgetClassNames[WidgetClassName] = self
2999 def self.to_eval
3000 WidgetClassName
3001 end
3002
3003 ################# old version
3004 # def initialize(parent=nil, keys=nil)
3005 # if keys.kind_of? Hash
3006 # keys = keys.dup
3007 # @classname = keys.delete('classname') if keys.key?('classname')
3008 # @colormap = keys.delete('colormap') if keys.key?('colormap')
3009 # @container = keys.delete('container') if keys.key?('container')
3010 # @visual = keys.delete('visual') if keys.key?('visual')
3011 # end
3012 # super(parent, keys)
3013 # end
3014 #
3015 # def create_self
3016 # s = []
3017 # s << "-class" << @classname if @classname
3018 # s << "-colormap" << @colormap if @colormap
3019 # s << "-container" << @container if @container
3020 # s << "-visual" << @visual if @visual
3021 # tk_call 'frame', @path, *s
3022 # end
3023 #################
3024
3025 def initialize(parent=nil, keys=nil)
3026 if parent.kind_of? Hash
3027 keys = _symbolkey2str(parent)
3028 else
3029 if keys
3030 keys = _symbolkey2str(keys)
3031 keys['parent'] = parent
3032 else
3033 keys = {'parent'=>parent}
3034 end
3035 end
3036 if keys.key?('classname')
3037 keys['class'] = keys.delete('classname')
3038 end
3039 @classname = keys['class']
3040 @colormap = keys['colormap']
3041 @container = keys['container']
3042 @visual = keys['visual']
3043 super(keys)
3044 end
3045
3046 def create_self(keys)
3047 if keys and keys != None
3048 tk_call 'frame', @path, *hash_kv(keys)
3049 else
3050 tk_call 'frame', @path
3051 end
3052 end
3053 end
3054
3055 class TkLabel<TkWindow
3056 WidgetClassName = 'Label'.freeze
3057 WidgetClassNames[WidgetClassName] = self
3058 def self.to_eval
3059 WidgetClassName
3060 end
3061 def create_self(keys)
3062 if keys and keys != None
3063 tk_call 'label', @path, *hash_kv(keys)
3064 else
3065 tk_call 'label', @path
3066 end
3067 end
3068 def textvariable(v)
3069 configure 'textvariable', tk_trace_variable(v)
3070 end
3071 end
3072
3073 class TkButton<TkLabel
3074 WidgetClassNames['Button'] = self
3075 def TkButton.to_eval
3076 'Button'
3077 end
3078 def create_self(keys)
3079 if keys and keys != None
3080 tk_call 'button', @path, *hash_kv(keys)
3081 else
3082 tk_call 'button', @path
3083 end
3084 end
3085 def invoke
3086 tk_send 'invoke'
3087 end
3088 def flash
3089 tk_send 'flash'
3090 end
3091 end
3092
3093 class TkRadioButton<TkButton
3094 WidgetClassNames['Radiobutton'] = self
3095 def TkRadioButton.to_eval
3096 'Radiobutton'
3097 end
3098 def create_self(keys)
3099 if keys and keys != None
3100 tk_call 'radiobutton', @path, *hash_kv(keys)
3101 else
3102 tk_call 'radiobutton', @path
3103 end
3104 end
3105 def deselect
3106 tk_send 'deselect'
3107 end
3108 def select
3109 tk_send 'select'
3110 end
3111 def variable(v)
3112 configure 'variable', tk_trace_variable(v)
3113 end
3114 end
3115 TkRadiobutton = TkRadioButton
3116
3117 class TkCheckButton<TkRadioButton
3118 WidgetClassNames['Checkbutton'] = self
3119 def TkCheckButton.to_eval
3120 'Checkbutton'
3121 end
3122 def create_self(keys)
3123 if keys and keys != None
3124 tk_call 'checkbutton', @path, *hash_kv(keys)
3125 else
3126 tk_call 'checkbutton', @path
3127 end
3128 end
3129 def toggle
3130 tk_send 'toggle'
3131 end
3132 end
3133 TkCheckbutton = TkCheckButton
3134
3135 class TkMessage<TkLabel
3136 WidgetClassNames['Message'] = self
3137 def TkMessage.to_eval
3138 'Message'
3139 end
3140 def create_self(keys)
3141 if keys and keys != None
3142 tk_call 'message', @path, *hash_kv(keys)
3143 else
3144 tk_call 'message', @path
3145 end
3146 end
3147 end
3148
3149 class TkScale<TkWindow
3150 WidgetClassName = 'Scale'.freeze
3151 WidgetClassNames[WidgetClassName] = self
3152 def self.to_eval
3153 WidgetClassName
3154 end
3155
3156 def create_self(keys)
3157 if keys and keys != None
3158 tk_call 'scale', @path, *hash_kv(keys)
3159 else
3160 tk_call 'scale', @path
3161 end
3162 end
3163
3164 def get(x=None, y=None)
3165 number(tk_send('get', x, y))
3166 end
3167
3168 def coords(val=None)
3169 tk_split_list(tk_send('coords', val))
3170 end
3171
3172 def identify(x, y)
3173 tk_send('identify', x, y)
3174 end
3175
3176 def set(val)
3177 tk_send "set", val
3178 end
3179
3180 def value
3181 get
3182 end
3183
3184 def value= (val)
3185 set val
3186 end
3187 end
3188
3189 class TkScrollbar<TkWindow
3190 WidgetClassName = 'Scrollbar'.freeze
3191 WidgetClassNames[WidgetClassName] = self
3192 def self.to_eval
3193 WidgetClassName
3194 end
3195
3196 def create_self(keys)
3197 if keys and keys != None
3198 tk_call 'scrollbar', @path, *hash_kv(keys)
3199 else
3200 tk_call 'scrollbar', @path
3201 end
3202 end
3203
3204 def delta(deltax=None, deltay=None)
3205 number(tk_send('delta', deltax, deltay))
3206 end
3207
3208 def fraction(x=None, y=None)
3209 number(tk_send('fraction', x, y))
3210 end
3211
3212 def identify(x, y)
3213 tk_send('identify', x, y)
3214 end
3215
3216 def get
3217 ary1 = tk_send('get').split
3218 ary2 = []
3219 for i in ary1
3220 ary2.push number(i)
3221 end
3222 ary2
3223 end
3224
3225 def set(first, last)
3226 tk_send "set", first, last
3227 end
3228
3229 def activate(element=None)
3230 tk_send('activate', element)
3231 end
3232 end
3233
3234 class TkTextWin<TkWindow
3235 def create_self
3236 fail TypeError, "TkTextWin is abstract class"
3237 end
3238
3239 def bbox(index)
3240 tk_send 'bbox', index
3241 end
3242 def delete(first, last=None)
3243 tk_send 'delete', first, last
3244 end
3245 def get(*index)
3246 tk_send 'get', *index
3247 end
3248 def index(index)
3249 tk_send 'index', index
3250 end
3251 def insert(index, chars, *args)
3252 tk_send 'insert', index, chars, *args
3253 end
3254 def scan_mark(x, y)
3255 tk_send 'scan', 'mark', x, y
3256 end
3257 def scan_dragto(x, y)
3258 tk_send 'scan', 'dragto', x, y
3259 end
3260 def see(index)
3261 tk_send 'see', index
3262 end
3263 end
3264
3265 module TkTreatListItemFont
3266 include TkTreatItemFont
3267
3268 ItemCMD = ['itemconfigure', TkComm::None]
3269 def __conf_cmd(idx)
3270 ItemCMD[idx]
3271 end
3272
3273 def __item_pathname(tagOrId)
3274 self.path + ';' + tagOrId.to_s
3275 end
3276 end
3277
3278 class TkListbox<TkTextWin
3279 include TkTreatListItemFont
3280 include Scrollable
3281
3282 WidgetClassNames['Listbox'] = self
3283 def TkListbox.to_eval
3284 'Listbox'
3285 end
3286 def create_self(keys)
3287 if keys and keys != None
3288 tk_call 'listbox', @path, *hash_kv(keys)
3289 else
3290 tk_call 'listbox', @path
3291 end
3292 end
3293
3294 def activate(y)
3295 tk_send 'activate', y
3296 end
3297 def curselection
3298 list(tk_send('curselection'))
3299 end
3300 def get(*index)
3301 v = tk_send('get', *index)
3302 if index.size == 1
3303 v
3304 else
3305 tk_split_simplelist(v)
3306 end
3307 end
3308 def nearest(y)
3309 tk_send('nearest', y).to_i
3310 end
3311 def size
3312 tk_send('size').to_i
3313 end
3314 def selection_anchor(index)
3315 tk_send 'selection', 'anchor', index
3316 end
3317 def selection_clear(first, last=None)
3318 tk_send 'selection', 'clear', first, last
3319 end
3320 def selection_includes(index)
3321 bool(tk_send('selection', 'includes', index))
3322 end
3323 def selection_set(first, last=None)
3324 tk_send 'selection', 'set', first, last
3325 end
3326
3327 def itemcget(index, key)
3328 case key.to_s
3329 when 'text', 'label', 'show'
3330 tk_send 'itemcget', index, "-#{key}"
3331 else
3332 tk_tcl2ruby tk_send('itemcget', index, "-#{key}")
3333 end
3334 end
3335 def itemconfigure(index, key, val=None)
3336 if key.kind_of? Hash
3337 if (key['font'] || key[:font] ||
3338 key['kanjifont'] || key[:kanjifont] ||
3339 key['latinfont'] || key[:latinfont] ||
3340 key['asciifont'] || key[:asciifont] )
3341 tagfont_configure(index, _symbolkey2str(key))
3342 else
3343 tk_send 'itemconfigure', index, *hash_kv(key)
3344 end
3345
3346 else
3347 if (key == 'font' || key == :font ||
3348 key == 'kanjifont' || key == :kanjifont ||
3349 key == 'latinfont' || key == :latinfont ||
3350 key == 'asciifont' || key == :asciifont )
3351 tagfont_configure(index, {key=>val})
3352 else
3353 tk_call 'itemconfigure', index, "-#{key}", val
3354 end
3355 end
3356 end
3357
3358 def itemconfiginfo(index, key=nil)
3359 if key
3360 case key.to_s
3361 when 'text', 'label', 'show'
3362 conf = tk_split_simplelist(tk_send('itemconfigure',index,"-#{key}"))
3363 else
3364 conf = tk_split_list(tk_send('itemconfigure',index,"-#{key}"))
3365 end
3366 conf[0] = conf[0][1..-1]
3367 conf
3368 else
3369 tk_split_simplelist(tk_send('itemconfigure', index)).collect{|conflist|
3370 conf = tk_split_simplelist(conflist)
3371 conf[0] = conf[0][1..-1]
3372 case conf[0]
3373 when 'text', 'label', 'show'
3374 else
3375 if conf[3]
3376 if conf[3].index('{')
3377 conf[3] = tk_split_list(conf[3])
3378 else
3379 conf[3] = tk_tcl2ruby(conf[3])
3380 end
3381 end
3382 if conf[4]
3383 if conf[4].index('{')
3384 conf[4] = tk_split_list(conf[4])
3385 else
3386 conf[4] = tk_tcl2ruby(conf[4])
3387 end
3388 end
3389 end
3390 conf
3391 }
3392 end
3393 end
3394 end
3395
3396 module TkTreatMenuEntryFont
3397 include TkTreatItemFont
3398
3399 ItemCMD = ['entryconfigure', TkComm::None]
3400 def __conf_cmd(idx)
3401 ItemCMD[idx]
3402 end
3403
3404 def __item_pathname(tagOrId)
3405 self.path + ';' + tagOrId.to_s
3406 end
3407 end
3408
3409 class TkMenu<TkWindow
3410 include TkTreatMenuEntryFont
3411
3412 WidgetClassName = 'Menu'.freeze
3413 WidgetClassNames[WidgetClassName] = self
3414 def self.to_eval
3415 WidgetClassName
3416 end
3417 def create_self(keys)
3418 if keys and keys != None
3419 tk_call 'menu', @path, *hash_kv(keys)
3420 else
3421 tk_call 'menu', @path
3422 end
3423 end
3424 def activate(index)
3425 tk_send 'activate', index
3426 end
3427 def add(type, keys=nil)
3428 tk_send 'add', type, *hash_kv(keys)
3429 end
3430 def index(index)
3431 tk_send 'index', index
3432 end
3433 def invoke(index)
3434 tk_send 'invoke', index
3435 end
3436 def insert(index, type, keys=nil)
3437 tk_send 'insert', index, type, *hash_kv(keys)
3438 end
3439 def delete(index, last=None)
3440 tk_send 'delete', index, last
3441 end
3442 def popup(x, y, index=None)
3443 tk_call 'tk_popup', path, x, y, index
3444 end
3445 def post(x, y)
3446 tk_send 'post', x, y
3447 end
3448 def postcascade(index)
3449 tk_send 'postcascade', index
3450 end
3451 def postcommand(cmd=Proc.new)
3452 configure_cmd 'postcommand', cmd
3453 end
3454 def tearoffcommand(cmd=Proc.new)
3455 configure_cmd 'tearoffcommand', cmd
3456 end
3457 def menutype(index)
3458 tk_send 'type', index
3459 end
3460 def unpost
3461 tk_send 'unpost'
3462 end
3463 def yposition(index)
3464 number(tk_send('yposition', index))
3465 end
3466 def entrycget(index, key)
3467 case key.to_s
3468 when 'text', 'label', 'show'
3469 tk_send 'entrycget', index, "-#{key}"
3470 else
3471 tk_tcl2ruby tk_send('entrycget', index, "-#{key}")
3472 end
3473 end
3474 def entryconfigure(index, key, val=None)
3475 if key.kind_of? Hash
3476 if (key['font'] || key[:font] ||
3477 key['kanjifont'] || key[:kanjifont] ||
3478 key['latinfont'] || key[:latinfont] ||
3479 key['asciifont'] || key[:asciifont])
3480 tagfont_configure(index, _symbolkey2str(key))
3481 else
3482 tk_send 'entryconfigure', index, *hash_kv(key)
3483 end
3484
3485 else
3486 if (key == 'font' || key == :font ||
3487 key == 'kanjifont' || key == :kanjifont ||
3488 key == 'latinfont' || key == :latinfont ||
3489 key == 'asciifont' || key == :asciifont )
3490 tagfont_configure({key=>val})
3491 else
3492 tk_call 'entryconfigure', index, "-#{key}", val
3493 end
3494 end
3495 end
3496
3497 def entryconfiginfo(index, key=nil)
3498 if key
3499 case key.to_s
3500 when 'text', 'label', 'show'
3501 conf = tk_split_simplelist(tk_send('entryconfigure',index,"-#{key}"))
3502 else
3503 conf = tk_split_list(tk_send('entryconfigure',index,"-#{key}"))
3504 end
3505 conf[0] = conf[0][1..-1]
3506 conf
3507 else
3508 tk_split_simplelist(tk_send('entryconfigure', index)).collect{|conflist|
3509 conf = tk_split_simplelist(conflist)
3510 conf[0] = conf[0][1..-1]
3511 case conf[0]
3512 when 'text', 'label', 'show'
3513 else
3514 if conf[3]
3515 if conf[3].index('{')
3516 conf[3] = tk_split_list(conf[3])
3517 else
3518 conf[3] = tk_tcl2ruby(conf[3])
3519 end
3520 end
3521 if conf[4]
3522 if conf[4].index('{')
3523 conf[4] = tk_split_list(conf[4])
3524 else
3525 conf[4] = tk_tcl2ruby(conf[4])
3526 end
3527 end
3528 end
3529 conf
3530 }
3531 end
3532 end
3533 end
3534
3535 class TkMenuClone<TkMenu
3536 def initialize(parent, type=None)
3537 widgetname = nil
3538 if parent.kind_of? Hash
3539 keys = _symbolkey2str(parent)
3540 parent = keys.delete('parent')
3541 widgetname = keys.delete('widgetname')
3542 type = keys.delete('type'); type = None unless type
3543 end
3544 unless parent.kind_of?(TkMenu)
3545 fail ArgumentError, "parent must be TkMenu"
3546 end
3547 @parent = parent
3548 install_win(@parent.path, widgetname)
3549 tk_call @parent.path, 'clone', @path, type
3550 end
3551 end
3552
3553 module TkSystemMenu
3554 def initialize(parent, keys=nil)
3555 if parent.kind_of? Hash
3556 keys = _symbolkey2str(parent)
3557 parent = keys.delete('parent')
3558 end
3559 fail unless parent.kind_of? TkMenu
3560 @path = format("%s.%s", parent.path, self.type::SYSMENU_NAME)
3561 TkComm::Tk_WINDOWS[@path] = self
3562 if self.method(:create_self).arity == 0
3563 p 'create_self has no arg' if $DEBUG
3564 create_self
3565 configure(keys) if keys
3566 else
3567 p 'create_self has an arg' if $DEBUG
3568 create_self(keys)
3569 end
3570 end
3571 end
3572
3573 class TkSysMenu_Help<TkMenu
3574 # for all platform
3575 include TkSystemMenu
3576 SYSMENU_NAME = 'help'
3577 end
3578
3579 class TkSysMenu_System<TkMenu
3580 # for Windows
3581 include TkSystemMenu
3582 SYSMENU_NAME = 'system'
3583 end
3584
3585 class TkSysMenu_Apple<TkMenu
3586 # for Machintosh
3587 include TkSystemMenu
3588 SYSMENU_NAME = 'apple'
3589 end
3590
3591 class TkMenubutton<TkLabel
3592 WidgetClassNames['Menubutton'] = self
3593 def TkMenubutton.to_eval
3594 'Menubutton'
3595 end
3596 def create_self(keys)
3597 if keys and keys != None
3598 tk_call 'menubutton', @path, *hash_kv(keys)
3599 else
3600 tk_call 'menubutton', @path
3601 end
3602 end
3603 end
3604
3605 class TkOptionMenubutton<TkMenubutton
3606 class OptionMenu<TkMenu
3607 def initialize(parent)
3608 @path = parent.path + '.menu'
3609 TkComm::Tk_WINDOWS[@path] = self
3610 end
3611 end
3612
3613 def initialize(parent=nil, var=TkVariable.new, firstval=nil, *vals)
3614 if parent.kind_of Hash
3615 keys = _symbolkey2str(parent)
3616 parent = keys['parent']
3617 var = keys['variable'] if keys['variable']
3618 firstval, *vals = keys['values']
3619 end
3620 fail unless var.kind_of? TkVariable
3621 @variable = var
3622 firstval = @variable.value unless firstval
3623 @variable.value = firstval
3624 install_win(if parent then parent.path end)
3625 @menu = OptionMenu.new(self)
3626 tk_call 'tk_optionMenu', @path, @variable.id, firstval, *vals
3627 end
3628
3629 def value
3630 @variable.value
3631 end
3632
3633 def activate(index)
3634 @menu.activate(index)
3635 end
3636 def add(value)
3637 @menu.add('radiobutton', 'variable'=>@variable,
3638 'label'=>value, 'value'=>value)
3639 end
3640 def index(index)
3641 @menu.index(index)
3642 end
3643 def invoke(index)
3644 @menu.invoke(index)
3645 end
3646 def insert(index, value)
3647 @menu.add(index, 'radiobutton', 'variable'=>@variable,
3648 'label'=>value, 'value'=>value)
3649 end
3650 def delete(index, last=None)
3651 @menu.delete(index, last)
3652 end
3653 def yposition(index)
3654 @menu.yposition(index)
3655 end
3656 def menucget(index, key)
3657 @menu.cget(index, key)
3658 end
3659 def menuconfigure(index, key, val=None)
3660 @menu.configure(index, key, val)
3661 end
3662 def menuconfiginfo(index, key=nil)
3663 @menu.configinfo(index, key)
3664 end
3665 def entrycget(index, key)
3666 @menu.entrycget(index, key)
3667 end
3668 def entryconfigure(index, key, val=None)
3669 @menu.entryconfigure(index, key, val)
3670 end
3671 def entryconfiginfo(index, key=nil)
3672 @menu.entryconfiginfo(index, key)
3673 end
3674 end
3675
3676 module TkComposite
3677 include Tk
3678 extend Tk
3679
3680 def initialize(parent=nil, *args)
3681 if parent.kind_of? Hash
3682 keys = _symbolkey2str(parent)
3683 parent = keys['parent']
3684 keys['parent'] = @frame = TkFrame.new(parent)
3685 @path = @epath = @frame.path
3686 initialize_composite(keys)
3687 else
3688 @frame = TkFrame.new(parent)
3689 @path = @epath = @frame.path
3690 initialize_composite(*args)
3691 end
3692 end
3693
3694 def epath
3695 @epath
3696 end
3697
3698 def initialize_composite(*args) end
3699 private :initialize_composite
3700
3701 def delegate(option, *wins)
3702 unless @delegates
3703 @delegates = {}
3704 @delegates['DEFAULT'] = @frame
3705 end
3706 if @delegates[option].kind_of?(Array)
3707 for i in wins
3708 @delegates[option].push(i)
3709 end
3710 else
3711 @delegates[option] = wins
3712 end
3713 end
3714
3715 def configure(slot, value=None)
3716 if slot.kind_of? Hash
3717 slot.each{|slot,value| configure slot, value}
3718 else
3719 if @delegates and @delegates[slot]
3720 for i in @delegates[slot]
3721 if not i
3722 i = @delegates['DEFALUT']
3723 redo
3724 else
3725 last = i.configure(slot, value)
3726 end
3727 end
3728 last
3729 else
3730 super
3731 end
3732 end
3733 end
3734 end
3735
3736 module TkClipboard
3737 include Tk
3738 extend Tk
3739
3740 def clear
3741 tk_call 'clipboard', 'clear'
3742 end
3743 def get
3744 begin
3745 tk_call 'selection', 'get', '-selection', 'CLIPBOARD'
3746 rescue
3747 ''
3748 end
3749 end
3750 def set(data)
3751 clear
3752 append(data)
3753 end
3754 def append(data)
3755 tk_call 'clipboard', 'append', data
3756 end
3757
3758 module_function :clear, :set, :get, :append
3759 end
3760
3761 autoload :TkCanvas, 'tkcanvas'
3762 autoload :TkImage, 'tkcanvas'
3763 autoload :TkBitmapImage, 'tkcanvas'
3764 autoload :TkPhotoImage, 'tkcanvas'
3765 autoload :TkEntry, 'tkentry'
3766 autoload :TkSpinbox, 'tkentry'
3767 autoload :TkText, 'tktext'
3768 autoload :TkDialog, 'tkdialog'
3769 autoload :TkWarning, 'tkdialog'
3770 autoload :TkMenubar, 'tkmenubar'
3771 autoload :TkAfter, 'tkafter'
3772 autoload :TkPalette, 'tkpalette'
3773 autoload :TkFont, 'tkfont'
3774 autoload :TkVirtualEvent, 'tkvirtevent'
3775 autoload :TkBgError, 'tkbgerror'
3776 autoload :TkManageFocus, 'tkmngfocus'
3777 autoload :TkPalette, 'tkpalette'
3778 autoload :TkWinDDE, 'tkwinpkg'
3779 autoload :TkWinRegistry, 'tkwinpkg'
3780 autoload :TkMacResource, 'tkmacpkg'