ffi-tk 2009.11.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. data/CHANGELOG +748 -0
  2. data/MANIFEST +188 -0
  3. data/README.md +85 -0
  4. data/Rakefile +47 -0
  5. data/TODO.md +62 -0
  6. data/bin/rwish +33 -0
  7. data/doc/MIT_LICENSE +18 -0
  8. data/doc/TCL_LICENSE +39 -0
  9. data/example/choose_color.rb +22 -0
  10. data/example/choose_directory.rb +22 -0
  11. data/example/dialog.rb +37 -0
  12. data/example/hello.rb +11 -0
  13. data/example/message_box.rb +26 -0
  14. data/example/option_menu.rb +17 -0
  15. data/example/popup.rb +24 -0
  16. data/example/set_palette.rb +32 -0
  17. data/example/text.rb +47 -0
  18. data/example/tile/kroc_demo_small.rb +123 -0
  19. data/example/tile/kroc_rb_demo.rb +135 -0
  20. data/example/tile/notebook.rb +48 -0
  21. data/example/tile/theme_hello.rb +38 -0
  22. data/example/tile/treeview.rb +71 -0
  23. data/example/various.rb +25 -0
  24. data/example/wait.rb +16 -0
  25. data/ffi-tk.gemspec +33 -0
  26. data/lib/ffi-tk.rb +76 -0
  27. data/lib/ffi-tk/command.rb +39 -0
  28. data/lib/ffi-tk/command/after.rb +36 -0
  29. data/lib/ffi-tk/command/bell.rb +34 -0
  30. data/lib/ffi-tk/command/bind.rb +11 -0
  31. data/lib/ffi-tk/command/bindtags.rb +69 -0
  32. data/lib/ffi-tk/command/cget.rb +92 -0
  33. data/lib/ffi-tk/command/choose_color.rb +29 -0
  34. data/lib/ffi-tk/command/choose_directory.rb +45 -0
  35. data/lib/ffi-tk/command/clipboard.rb +102 -0
  36. data/lib/ffi-tk/command/configure.rb +88 -0
  37. data/lib/ffi-tk/command/destroy.rb +12 -0
  38. data/lib/ffi-tk/command/dialog.rb +54 -0
  39. data/lib/ffi-tk/command/event.rb +79 -0
  40. data/lib/ffi-tk/command/focus.rb +70 -0
  41. data/lib/ffi-tk/command/font.rb +124 -0
  42. data/lib/ffi-tk/command/get_open_file.rb +85 -0
  43. data/lib/ffi-tk/command/get_save_file.rb +83 -0
  44. data/lib/ffi-tk/command/grab.rb +141 -0
  45. data/lib/ffi-tk/command/grid.rb +246 -0
  46. data/lib/ffi-tk/command/image.rb +79 -0
  47. data/lib/ffi-tk/command/lower.rb +23 -0
  48. data/lib/ffi-tk/command/message_box.rb +65 -0
  49. data/lib/ffi-tk/command/option_menu.rb +8 -0
  50. data/lib/ffi-tk/command/pack.rb +99 -0
  51. data/lib/ffi-tk/command/place.rb +91 -0
  52. data/lib/ffi-tk/command/popup.rb +14 -0
  53. data/lib/ffi-tk/command/raise.rb +25 -0
  54. data/lib/ffi-tk/command/scrollable.rb +151 -0
  55. data/lib/ffi-tk/command/selection.rb +132 -0
  56. data/lib/ffi-tk/command/set_palette.rb +9 -0
  57. data/lib/ffi-tk/command/tk_cmd.rb +155 -0
  58. data/lib/ffi-tk/command/vars.rb +82 -0
  59. data/lib/ffi-tk/command/wait.rb +39 -0
  60. data/lib/ffi-tk/command/winfo.rb +668 -0
  61. data/lib/ffi-tk/command/wm.rb +1025 -0
  62. data/lib/ffi-tk/core_extensions.rb +154 -0
  63. data/lib/ffi-tk/event/data.rb +60 -0
  64. data/lib/ffi-tk/event/handler.rb +44 -0
  65. data/lib/ffi-tk/ffi/tcl.rb +92 -0
  66. data/lib/ffi-tk/ffi/tcl/cmd_proc.rb +10 -0
  67. data/lib/ffi-tk/ffi/tcl/eval_result.rb +148 -0
  68. data/lib/ffi-tk/ffi/tcl/interp.rb +95 -0
  69. data/lib/ffi-tk/ffi/tcl/obj.rb +89 -0
  70. data/lib/ffi-tk/ffi/tcl/time.rb +36 -0
  71. data/lib/ffi-tk/ffi/tk.rb +35 -0
  72. data/lib/ffi-tk/geometry.rb +32 -0
  73. data/lib/ffi-tk/thread_sender.rb +26 -0
  74. data/lib/ffi-tk/tk.rb +222 -0
  75. data/lib/ffi-tk/variable.rb +46 -0
  76. data/lib/ffi-tk/widget.rb +68 -0
  77. data/lib/ffi-tk/widget/button.rb +41 -0
  78. data/lib/ffi-tk/widget/canvas.rb +806 -0
  79. data/lib/ffi-tk/widget/canvas/arc.rb +18 -0
  80. data/lib/ffi-tk/widget/canvas/bitmap.rb +13 -0
  81. data/lib/ffi-tk/widget/canvas/image.rb +10 -0
  82. data/lib/ffi-tk/widget/canvas/item.rb +170 -0
  83. data/lib/ffi-tk/widget/canvas/line.rb +16 -0
  84. data/lib/ffi-tk/widget/canvas/oval.rb +15 -0
  85. data/lib/ffi-tk/widget/canvas/polygon.rb +16 -0
  86. data/lib/ffi-tk/widget/canvas/rectangle.rb +15 -0
  87. data/lib/ffi-tk/widget/canvas/text.rb +15 -0
  88. data/lib/ffi-tk/widget/canvas/window.rb +11 -0
  89. data/lib/ffi-tk/widget/checkbutton.rb +63 -0
  90. data/lib/ffi-tk/widget/entry.rb +208 -0
  91. data/lib/ffi-tk/widget/frame.rb +12 -0
  92. data/lib/ffi-tk/widget/label.rb +26 -0
  93. data/lib/ffi-tk/widget/labelframe.rb +7 -0
  94. data/lib/ffi-tk/widget/listbox.rb +192 -0
  95. data/lib/ffi-tk/widget/menu.rb +318 -0
  96. data/lib/ffi-tk/widget/menubutton.rb +7 -0
  97. data/lib/ffi-tk/widget/message.rb +36 -0
  98. data/lib/ffi-tk/widget/panedwindow.rb +164 -0
  99. data/lib/ffi-tk/widget/radiobutton.rb +43 -0
  100. data/lib/ffi-tk/widget/root.rb +8 -0
  101. data/lib/ffi-tk/widget/scale.rb +44 -0
  102. data/lib/ffi-tk/widget/scrollbar.rb +114 -0
  103. data/lib/ffi-tk/widget/spinbox.rb +198 -0
  104. data/lib/ffi-tk/widget/text.rb +893 -0
  105. data/lib/ffi-tk/widget/text/peer.rb +10 -0
  106. data/lib/ffi-tk/widget/tile.rb +70 -0
  107. data/lib/ffi-tk/widget/tile/button.rb +8 -0
  108. data/lib/ffi-tk/widget/tile/checkbutton.rb +8 -0
  109. data/lib/ffi-tk/widget/tile/combobox.rb +43 -0
  110. data/lib/ffi-tk/widget/tile/entry.rb +8 -0
  111. data/lib/ffi-tk/widget/tile/frame.rb +13 -0
  112. data/lib/ffi-tk/widget/tile/label.rb +9 -0
  113. data/lib/ffi-tk/widget/tile/labelframe.rb +8 -0
  114. data/lib/ffi-tk/widget/tile/menubutton.rb +8 -0
  115. data/lib/ffi-tk/widget/tile/notebook.rb +93 -0
  116. data/lib/ffi-tk/widget/tile/panedwindow.rb +9 -0
  117. data/lib/ffi-tk/widget/tile/progressbar.rb +59 -0
  118. data/lib/ffi-tk/widget/tile/radiobutton.rb +8 -0
  119. data/lib/ffi-tk/widget/tile/scale.rb +8 -0
  120. data/lib/ffi-tk/widget/tile/scrollbar.rb +41 -0
  121. data/lib/ffi-tk/widget/tile/separator.rb +23 -0
  122. data/lib/ffi-tk/widget/tile/sizegrip.rb +24 -0
  123. data/lib/ffi-tk/widget/tile/style.rb +114 -0
  124. data/lib/ffi-tk/widget/tile/treeview.rb +414 -0
  125. data/lib/ffi-tk/widget/toplevel.rb +14 -0
  126. data/spec/ffi-tk/command/bindtags.rb +18 -0
  127. data/spec/ffi-tk/command/clipboard.rb +18 -0
  128. data/spec/ffi-tk/command/font.rb +67 -0
  129. data/spec/ffi-tk/command/grid.rb +6 -0
  130. data/spec/ffi-tk/command/image.rb +26 -0
  131. data/spec/ffi-tk/command/pack.rb +20 -0
  132. data/spec/ffi-tk/command/place.rb +20 -0
  133. data/spec/ffi-tk/command/selection.rb +13 -0
  134. data/spec/ffi-tk/command/vars.rb +32 -0
  135. data/spec/ffi-tk/command/winfo.rb +233 -0
  136. data/spec/ffi-tk/command/wm.rb +185 -0
  137. data/spec/ffi-tk/event.rb +95 -0
  138. data/spec/ffi-tk/tile/button.rb +51 -0
  139. data/spec/ffi-tk/tile/checkbutton.rb +13 -0
  140. data/spec/ffi-tk/tile/combobox.rb +65 -0
  141. data/spec/ffi-tk/tile/entry.rb +61 -0
  142. data/spec/ffi-tk/tile/frame.rb +65 -0
  143. data/spec/ffi-tk/tile/label.rb +17 -0
  144. data/spec/ffi-tk/tile/labelframe.rb +13 -0
  145. data/spec/ffi-tk/tile/menubutton.rb +13 -0
  146. data/spec/ffi-tk/tile/notebook.rb +103 -0
  147. data/spec/ffi-tk/tile/panedwindow.rb +13 -0
  148. data/spec/ffi-tk/tile/progressbar.rb +78 -0
  149. data/spec/ffi-tk/tile/radiobutton.rb +13 -0
  150. data/spec/ffi-tk/tile/scale.rb +13 -0
  151. data/spec/ffi-tk/tile/scrollbar.rb +43 -0
  152. data/spec/ffi-tk/tile/separator.rb +22 -0
  153. data/spec/ffi-tk/tile/sizegrip.rb +13 -0
  154. data/spec/ffi-tk/tile/style.rb +161 -0
  155. data/spec/ffi-tk/tile/treeview.rb +101 -0
  156. data/spec/ffi-tk/variable.rb +24 -0
  157. data/spec/ffi-tk/widget/button.rb +22 -0
  158. data/spec/ffi-tk/widget/canvas.rb +169 -0
  159. data/spec/ffi-tk/widget/checkbutton.rb +44 -0
  160. data/spec/ffi-tk/widget/entry.rb +155 -0
  161. data/spec/ffi-tk/widget/frame.rb +8 -0
  162. data/spec/ffi-tk/widget/label.rb +16 -0
  163. data/spec/ffi-tk/widget/labelframe.rb +12 -0
  164. data/spec/ffi-tk/widget/listbox.rb +19 -0
  165. data/spec/ffi-tk/widget/menu.rb +12 -0
  166. data/spec/ffi-tk/widget/menubutton.rb +12 -0
  167. data/spec/ffi-tk/widget/message.rb +12 -0
  168. data/spec/ffi-tk/widget/panedwindow.rb +12 -0
  169. data/spec/ffi-tk/widget/radiobutton.rb +12 -0
  170. data/spec/ffi-tk/widget/root.rb +9 -0
  171. data/spec/ffi-tk/widget/scale.rb +12 -0
  172. data/spec/ffi-tk/widget/scrollbar.rb +12 -0
  173. data/spec/ffi-tk/widget/spinbox.rb +12 -0
  174. data/spec/ffi-tk/widget/text.rb +246 -0
  175. data/spec/ffi-tk/widget/toplevel.rb +12 -0
  176. data/spec/helper.rb +3 -0
  177. data/tasks/authors.rake +21 -0
  178. data/tasks/bacon.rake +66 -0
  179. data/tasks/changelog.rake +18 -0
  180. data/tasks/gem.rake +22 -0
  181. data/tasks/gem_setup.rake +113 -0
  182. data/tasks/grancher.rake +12 -0
  183. data/tasks/manifest.rake +4 -0
  184. data/tasks/rcov.rake +17 -0
  185. data/tasks/release.rake +65 -0
  186. data/tasks/reversion.rake +8 -0
  187. data/tasks/setup.rake +12 -0
  188. data/tasks/ycov.rake +84 -0
  189. metadata +261 -0
@@ -0,0 +1,46 @@
1
+ module Tk
2
+ # This class is used for communication of variables with Tcl.
3
+ class Variable
4
+ attr_reader :name, :tcl_name, :bytesize
5
+
6
+ def initialize(name, value = None)
7
+ @name = name.freeze
8
+ @tcl_name = "$#{name}".freeze
9
+ set(value) unless None == value
10
+ end
11
+
12
+ def get
13
+ Tk.execute('set', name)
14
+ rescue RuntimeError
15
+ raise NameError, "can't read %p: no such variable" % [name]
16
+ end
17
+
18
+ def set(value)
19
+ Tk.execute_only('set', name, value)
20
+ end
21
+
22
+ def unset
23
+ Tk.execute_only('unset', name)
24
+ end
25
+
26
+ def to_tcl
27
+ TclString.new(name)
28
+ end
29
+
30
+ def to_s
31
+ get.to_s
32
+ end
33
+
34
+ def to_i
35
+ get.to_i
36
+ end
37
+
38
+ def to_boolean
39
+ get.to_boolean
40
+ end
41
+
42
+ def to_f
43
+ get.to_f
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,68 @@
1
+ module Tk
2
+ class Widget
3
+ include Pack, Destroy, Bind, Bindtags, WM, Winfo, Grid, Clipboard, Place, TkCmd
4
+
5
+ attr_reader :tk_parent, :tk_pathname
6
+
7
+ def self.tk_command
8
+ raise NotImplementedError, "Implement in subclass"
9
+ end
10
+
11
+ def initialize(tk_parent = Tk.root, options = None)
12
+ if tk_parent.respond_to?(:to_tcl_options?)
13
+ tk_parent, options = Tk.root, tk_parent
14
+ end
15
+
16
+ if !options || None == options
17
+ options = {}
18
+ else
19
+ options = options.dup
20
+ end
21
+
22
+ @tk_parent = tk_parent
23
+
24
+ yield(options) if block_given? && !options[:command]
25
+
26
+ command = self.class.tk_command
27
+ Tk.execute(command, assign_pathname, options.to_tcl_options?)
28
+ end
29
+
30
+ def to_tcl
31
+ tk_pathname.dump
32
+ end
33
+
34
+ def focus(option = None)
35
+ Focus.focus(self, option)
36
+ end
37
+
38
+ def focus_next
39
+ Focus.next(self)
40
+ end
41
+
42
+ def focus_prev
43
+ Focus.prev(self)
44
+ end
45
+
46
+ def raise(above = None)
47
+ Raise.raise(self, above)
48
+ end
49
+
50
+ def lower(below = None)
51
+ Lower.lower(self, below)
52
+ end
53
+
54
+ def execute(command, *args)
55
+ Tk.execute(tk_pathname, command, *args)
56
+ end
57
+
58
+ def execute_only(command, *args)
59
+ Tk.execute_only(tk_pathname, command, *args)
60
+ end
61
+
62
+ private
63
+
64
+ def assign_pathname
65
+ @tk_pathname = Tk.register_object(tk_parent, self)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,41 @@
1
+ module Tk
2
+ # A button is a widget that displays a textual string, bitmap or image.
3
+ # If text is displayed, it must all be in a single font, but it can occupy
4
+ # multiple lines on the screen (if it contains newlines or if wrapping occurs
5
+ # because of the wrapLength option) and one of the characters may optionally
6
+ # be underlined using the underline option.
7
+ # It can display itself in either of three different ways, according to the
8
+ # state option; it can be made to appear raised, sunken, or flat; and it can
9
+ # be made to flash.
10
+ # When a user invokes the button (by pressing mouse button 1 with the cursor
11
+ # over the button), then the command specified in the -command option is
12
+ # invoked.
13
+ class Button < Widget
14
+ include Cget, Configure
15
+
16
+ def self.tk_command; 'button'; end
17
+
18
+ # TODO: implement custom procs
19
+ def initialize(parent = Tk.root, options = None, &block)
20
+ if block
21
+ options = {} unless options.respond_to?(:[]=)
22
+ options[:command] = register_command(:command, &block)
23
+ end
24
+
25
+ super
26
+ end
27
+
28
+ def destroy
29
+ unregister_commands
30
+ super
31
+ end
32
+
33
+ def invoke
34
+ execute_only('invoke')
35
+ end
36
+
37
+ def flash
38
+ execute_only('flash')
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,806 @@
1
+ module Tk
2
+ # Canvas widgets implement structured graphics.
3
+ #
4
+ # A canvas displays any number of items, which may be things like rectangles,
5
+ # circles, lines, and text.
6
+ # Items may be manipulated (e.g. moved or re-colored) and commands may be
7
+ # associated with items in much the same way that the bind command allows
8
+ # commands to be bound to widgets.
9
+ # For example, a particular command may be associated with the <Button-1>
10
+ # event so that the command is invoked whenever button 1 is pressed with the
11
+ # mouse cursor over an item.
12
+ # This means that items in a canvas can have behaviors defined.
13
+ class Canvas < Widget
14
+ require "ffi-tk/widget/canvas/item.rb"
15
+ require "ffi-tk/widget/canvas/arc.rb"
16
+ require "ffi-tk/widget/canvas/bitmap.rb"
17
+ require "ffi-tk/widget/canvas/image.rb"
18
+ require "ffi-tk/widget/canvas/line.rb"
19
+ require "ffi-tk/widget/canvas/oval.rb"
20
+ require "ffi-tk/widget/canvas/polygon.rb"
21
+ require "ffi-tk/widget/canvas/rectangle.rb"
22
+ require "ffi-tk/widget/canvas/text.rb"
23
+ require "ffi-tk/widget/canvas/window.rb"
24
+
25
+ include Cget, Configure
26
+
27
+ def self.tk_command; 'canvas'; end
28
+
29
+ # For each item that meets the constraints specified by +search_spec+ and
30
+ # the +args+, add +tag+ to the list of tags associated with the item if it
31
+ # is not already present on that list.
32
+ # It is possible that no items will satisfy the constraints given by
33
+ # +search_spec+ and +args+, in which case the command has no effect.
34
+ def addtag(tag, search_spec, *args)
35
+ execute_only(:addtag, tag, search_spec, *args)
36
+ end
37
+
38
+ # Selects the item just after (above) the one given by +tag_or_id+ in the
39
+ # display list.
40
+ # If +tag_or_id+ denotes more than one item, then the last (topmost) of
41
+ # these items in the display list is used.
42
+ def addtag_above(tag, tag_or_id)
43
+ execute_only(:addtag, tag, :above, tag_or_id)
44
+ end
45
+
46
+ # Selects all the items in the canvas.
47
+ def addtag_all(tag)
48
+ execute_only(:addtag, tag, :all)
49
+ end
50
+
51
+ # Selects the item just before (below) the one given by +tag_or_id+ in the
52
+ # display list.
53
+ # If +tag_or_id+ denotes more than one item, then the first (lowest) of
54
+ # these items in the display list is used.
55
+ def addtag_below(tag, tag_or_id)
56
+ execute_only(:addtag, tag, :below, tag_or_id)
57
+ end
58
+
59
+ # Selects the item closest to the point given by +x+ and +y+.
60
+ # If more than one item is at the same closest distance (e.g. two items
61
+ # overlap the point), then the top-most of these items (the last one in the
62
+ # display list) is used.
63
+ #
64
+ # If +halo+ is specified, then it must be a non-negative value.
65
+ # Any item closer than +halo+ to the point is considered to overlap it.
66
+ #
67
+ # The +start+ argument may be used to step circularly through all the
68
+ # closest items.
69
+ # If +start+ is specified, it names an item using a tag or id (if by tag, it
70
+ # selects the first item in the display list with the given tag).
71
+ # Instead of selecting the topmost closest item, this form will select the
72
+ # topmost closest item that is below +start+ in the display list; if no such
73
+ # item exists, then the selection behaves as if the +start+ argument had not
74
+ # been specified.
75
+ def addtag_closest(tag, x, y, halo = None, start = None)
76
+ execute_only(:addtag, tag, :closest, x, y, halo, start)
77
+ end
78
+
79
+ # Selects all the items completely enclosed within the rectangular region
80
+ # given by +x1+, +y1+, +x2+, and +y2+.
81
+ # +x1+ must be no greater then +x2+ and +y1+ must be no greater than +y2+.
82
+ def addtag_enclosed(tag, x1, y1, x2, y2)
83
+ execute_only(:addtag, tag, :enclosed, x1, y1, x2, y2)
84
+ end
85
+
86
+ # Selects all the items that overlap or are enclosed within the rectangular
87
+ # region given by +x1+, +y1+, +x2+, and +y2+.
88
+ # +x1+ must be no greater then +x2+ and +y1+ must be no greater than +y2+.
89
+ def addtag_overlapping(tag, x1, y1, x2, y2)
90
+ execute_only(:addtag, tag, :overlapping, x1, y1, x2, y2)
91
+ end
92
+
93
+ # Selects all the items given by +tag_or_id+.
94
+ def addtag_withtag(tag, tag_or_id)
95
+ execute_only(:addtag, tag, :withtag, tag_or_id)
96
+ end
97
+
98
+ # Returns a list with four elements giving an approximate bounding box for
99
+ # all the items named by the +tags_or_ids+ argument.
100
+ # The list has the form `[x1, y1, x2, y2]` such that the drawn areas of all
101
+ # the named elements are within the region bounded by x1 on the left, x2 on
102
+ # the right, y1 on the top, and y2 on the bottom.
103
+ # The return value may overestimate the actual bounding box by a few pixels.
104
+ # If no items match any of the +tags_or_ids+ argument or if the matching
105
+ # items have empty bounding boxes (i.e. they have nothing to display) then
106
+ # nil is returned.
107
+ def bbox(*tags_or_ids)
108
+ execute(:bbox, *tags_or_ids).to_a?(&:to_i)
109
+ end
110
+
111
+ # This method associates +command+ with all the items given by +tag_or_id+
112
+ # such that whenever the event sequence given by +sequence+ occurs for one
113
+ # of the items the command will be invoked.
114
+ #
115
+ # This widget command is similar to the bind command except that it operates
116
+ # on items in a canvas rather than entire widgets.
117
+ # See the bind manual entry for complete details on the syntax of +sequence+
118
+ # and the substitutions performed on command before invoking it.
119
+ #
120
+ # If all arguments are specified then a new binding is created, replacing
121
+ # any existing binding for the same +sequence+ and +tag_or_id+.
122
+ # See [bind_append] for information of how augment an existing binding
123
+ # instead of replacing it.
124
+ #
125
+ # In this case the return value is nil.
126
+ #
127
+ # If +command+ is omitted then the method returns the command associated
128
+ # with +tag_or_id+ and +sequence+ (an error occurs if there is no such binding).
129
+ # If both +command+ and +sequence+ are omitted then the command returns a list
130
+ # of all the sequences for which bindings have been defined for +tag_or_id+.
131
+ #
132
+ # The only events for which bindings may be specified are those related to
133
+ # the mouse and keyboard (such as Enter, Leave, ButtonPress, Motion, and
134
+ # KeyPress) or virtual events.
135
+ # The handling of events in canvases uses the current item defined in ITEM
136
+ # IDS AND TAGS above.
137
+ # Enter and Leave events trigger for an item when it becomes the current
138
+ # item or ceases to be the current item; note that these events are
139
+ # different than Enter and Leave events for windows.
140
+ # Mouse-related events are directed to the current item, if any.
141
+ # Keyboard-related events are directed to the focus item, if any (see the
142
+ # focus widget command below for more on this).
143
+ # If a virtual event is used in a binding, that binding can trigger only if
144
+ # the virtual event is defined by an underlying mouse-related or
145
+ # keyboard-related event.
146
+ # It is possible for multiple bindings to match a particular event.
147
+ # This could occur, for example, if one binding is associated with the
148
+ # item's id and another is associated with one of the item's tags.
149
+ # When this occurs, all of the matching bindings are invoked.
150
+ # A binding associated with the all tag is invoked first, followed by one
151
+ # binding for each of the item's tags (in order), followed by a binding
152
+ # associated with the item's id.
153
+ # If there are multiple matching bindings for a single tag, then only the
154
+ # most specific binding is invoked.
155
+ # A continue command in a binding script terminates that script, and a
156
+ # break command terminates that script and skips any remaining scripts for
157
+ # the event, just as for the bind command.
158
+ # If bindings have been created for a canvas window using the bind command,
159
+ # then they are invoked in addition to bindings created for the canvas's
160
+ # items using the bind widget command.
161
+ # The bindings for items will be invoked before any of the bindings for
162
+ # the window as a whole.
163
+ def bind(tag_or_id, sequence = None, &script)
164
+ unless script
165
+ if None == sequence
166
+ return Tk.execute(:bind, tag_or_id)
167
+ else
168
+ return Tk.execute(:bind, tag_or_id, sequence)
169
+ end
170
+ end
171
+
172
+ name = "#{tag_or_id}_#{tag_name}".scan(/\w+/).join('_')
173
+ @events ||= {}
174
+ unregister_event(name)
175
+
176
+ Event::Handler.register_custom(script) do |id|
177
+ code = "%s bind %s %s { ::RubyFFI::event %d '' %s }"
178
+ props = Event::Data::PROPERTIES.transpose[0].join(' ')
179
+ tcl = code % [tk_pathname, tag_or_id, sequence, id, props]
180
+ Tk.interp.eval(tcl)
181
+ @events[name] = id
182
+ end
183
+ end
184
+
185
+ # Given a window x-coordinate in the canvas +screenx+, this command returns
186
+ # the canvas x-coordinate that is displayed at that location.
187
+ # If +gridspacing+ is true, then the canvas coordinate is rounded to the
188
+ # nearest multiple of gridspacing units.
189
+ def canvasx(screenx, gridspacing = false)
190
+ execute(:canvasx, screenx, gridspacing ? :gridspacing : None)
191
+ end
192
+
193
+ # Given a window y-coordinate in the canvas +screeny+ this command returns
194
+ # the canvas y-coordinate that is displayed at that location.
195
+ # If +gridspacing+ is true, then the canvas coordinate is rounded to the
196
+ # nearest multiple of gridspacing units.
197
+ def canvasy(screeny, gridspacing = false)
198
+ execute(:canvasy, screeny, gridspacing ? :gridspacing : None)
199
+ end
200
+
201
+ # Query or modify the coordinates that define an item.
202
+ # If no coordinates are specified, this command returns a list whose
203
+ # elements are the coordinates of the item named by +tag_or_id+.
204
+ # If coordinates are specified, then they replace the current coordinates
205
+ # for the named item.
206
+ # If +tag_or_id+ refers to multiple items, then the first one in the display
207
+ # list is used.
208
+ def coords(tag_or_id, *coord_list)
209
+ if coord_list.empty?
210
+ execute(:coords, tag_or_id).to_a
211
+ else
212
+ execute_only(:coords, tag_or_id, *coord_list.flatten)
213
+ end
214
+ end
215
+
216
+ # Create a new item in pathName of type type.
217
+ # The exact format of the arguments after type depends on type, but usually
218
+ # they consist of the coordinates for one or more points, followed by
219
+ # specifications for zero or more item options.
220
+ # See the subsections on individual item types below for more on the syntax
221
+ # of this command.
222
+ # This command returns the id for the new item.
223
+ def create(type, coord_list, options = {})
224
+ options = options ? options.to_tcl_options : None
225
+ id = execute(:create, type, coord_list, options).to_i
226
+ Item.create(self, type, id)
227
+ end
228
+
229
+ # Items of type arc appear on the display as arc-shaped regions.
230
+ # An arc is a section of an oval delimited by two angles (specified by the
231
+ # :start and :extent options) and displayed in one of several ways
232
+ # (specified by the :style option).
233
+ def create_arc(x1, y1, x2, y2, options = {})
234
+ create(:arc, [x1, y1, x2, y2], options)
235
+ end
236
+
237
+ # Items of type bitmap appear on the display as images with two colors,
238
+ # foreground and background.
239
+ def create_bitmap(x, y, options = {})
240
+ create(:bitmap, [x, y], options)
241
+ end
242
+
243
+ # Items of type image are used to display images on a canvas.
244
+ def create_image(x, y, options = {})
245
+ create(:image, [x, y], options)
246
+ end
247
+
248
+ # Items of type line appear on the display as one or more connected line
249
+ # segments or curves.
250
+ # Line items support coordinate indexing operations using the methods
251
+ # [dchars], [index], and [insert].
252
+ def create_line(*arguments)
253
+ options, coords = arguments.partition{|arg| arg.respond_to?(:to_tcl_options) }
254
+ create(:line, coords, options.first)
255
+ end
256
+
257
+ # Items of type oval appear as circular or oval regions on the display.
258
+ # Each oval may have an outline, a fill, or both.
259
+ def create_oval(x1, y1, x2, y2, options = {})
260
+ create(:oval, [x1, y1, x2, y2], options)
261
+ end
262
+
263
+ # Items of type polygon appear as polygonal or curved filled regions on the
264
+ # display. Polygon items support coordinate indexing operations using the
265
+ # methods [dchars], [index], or [insert].
266
+ def create_polygon(*arguments)
267
+ options, coords = arguments.partition{|arg| arg.respond_to?(:to_tcl_options) }
268
+ create(:polygon, coords, options.first)
269
+ end
270
+
271
+ # Items of type rectangle appear as rectangular regions on the display.
272
+ # Each rectangle may have an outline, a fill, or both.
273
+ def create_rectangle(x1, y1, x2, y2, options = {})
274
+ create(:rectangle, [x1, y1, x2, y2], options)
275
+ end
276
+
277
+ # A text item displays a string of characters on the screen in one or more
278
+ # lines. Text items support indexing and selection, along with the following
279
+ # text-related methods: [dchars], [focus], [icursor], [index], [insert], and
280
+ # [select].
281
+ def create_text(x, y, options = {})
282
+ create(:text, [x, y], options)
283
+ end
284
+
285
+ # Items of type window cause a particular window to be displayed at a given
286
+ # position on the canvas.
287
+ def create_window(x, y, options = {})
288
+ create(:window, [x, y], options)
289
+ end
290
+
291
+ # For each item given by +tag_or_id+, delete the characters, or coordinates, in
292
+ # the range given by +first+ and +last+, inclusive.
293
+ # If some of the items given by +tag_or_id+ do not support indexing
294
+ # operations then they ignore dchars.
295
+ # Text items interpret +first+ and +last+ as indices to a character, line and
296
+ # polygon items interpret them indices to a coordinate (an x,y pair).
297
+ # Indices are described in INDICES above.
298
+ # If +last+ is omitted, it defaults to +first+.
299
+ # This command returns nil.
300
+ def dchars(tag_or_id, first, last = None)
301
+ execute_only(:dchars, tag_or_id, first, last)
302
+ end
303
+
304
+ # Delete the items associated with the given +tags_or_ids+, and return nil.
305
+ def delete(*tags_or_ids)
306
+ execute_only(:delete, *tags_or_ids)
307
+ end
308
+
309
+ # For each of the items given by +tag_or_id+, delete the tag given by
310
+ # +tag_to_delete+ from the list of those associated with the item.
311
+ # If an item does not have the tag +tag_to_delete+ then the item is
312
+ # unaffected by the command.
313
+ # If +tag_to_delete+ is omitted then it defaults to +tag_or_id+.
314
+ # This command returns nil.
315
+ def dtag(tag_or_id, tag_to_delete = None)
316
+ execute_only(:dtag, tag_or_id, tag_to_delete)
317
+ end
318
+
319
+ # This command returns a list consisting of all the items that meet the
320
+ # constraints specified by +search_command+ and +args+.
321
+ # +search_command+ and +args+ have any of the forms accepted by the [addtag]
322
+ # method.
323
+ # The items are returned in stacking order, with the lowest item first.
324
+ def find(search_command, *args)
325
+ execute(:find, search_command, *args)
326
+ end
327
+
328
+ def find_above(tag, tag_or_id)
329
+ execute(:find, tag, :above, tag_or_id)
330
+ end
331
+
332
+ def find_all(tag)
333
+ execute(:find, tag, :all)
334
+ end
335
+
336
+ def find_below(tag, tag_or_id)
337
+ execute(:find, tag, :below, tag_or_id)
338
+ end
339
+
340
+ def find_closest(tag, x, y, halo = None, start = None)
341
+ execute(:find, tag, :closest, x, y, halo, start)
342
+ end
343
+
344
+ def find_enclosed(tag, x1, y1, x2, y2)
345
+ execute(:find, tag, :enclosed, x1, y1, x2, y2)
346
+ end
347
+
348
+ def find_overlapping(tag, x1, y1, x2, y2)
349
+ execute(:find, tag, :overlapping, x1, y1, x2, y2)
350
+ end
351
+
352
+ def find_withtag(tag, tag_or_id)
353
+ execute(:find, tag, :withtag, tag_or_id)
354
+ end
355
+
356
+ # Set the keyboard focus for the canvas widget to the item given by
357
+ # +tag_or_id+.
358
+ # If +tag_or_id+ refers to several items, then the focus is set to the
359
+ # first such item in the display list that supports the insertion cursor.
360
+ # If +tag_or_id+ does not refer to any items, or if none of them support the
361
+ # insertion cursor, then the focus is not changed.
362
+ # If +tag_or_id+ is an empty string, then the focus item is reset so that no
363
+ # item has the focus.
364
+ # If +tag_or_id+ is not specified then the command returns the id for the item
365
+ # that currently has the focus, or an empty string if no item has the
366
+ # focus. Once the focus has been set to an item, the item will display the
367
+ # insertion cursor and all keyboard events will be directed to that item.
368
+ # The focus item within a canvas and the focus window on the screen (set
369
+ # with the focus command) are totally independent: a given item does not
370
+ # actually have the input focus unless (a) its canvas is the focus window
371
+ # and (b) the item is the focus item within the canvas.
372
+ # In most cases it is advisable to follow the focus widget command with the
373
+ # focus command to set the focus window to the canvas (if it was not there
374
+ # already).
375
+ def focus(tag_or_id)
376
+ execute_only(:focus, tag_or_id)
377
+ end
378
+
379
+ # Return a list whose elements are the tags associated with the item given
380
+ # by +tag_or_id+.
381
+ # If +tag_or_id+ refers to more than one item, then the tags are returned from
382
+ # the first such item in the display list.
383
+ # If +tag_or_id+ does not refer to any items, or if the item contains no tags,
384
+ # then an empty string is returned.
385
+ def gettags(tag_or_id)
386
+ execute(:gettags, tag_or_id).to_a
387
+ end
388
+
389
+ # Set the position of the insertion cursor for the item(s) given by +tag_or_id+
390
+ # to just before the character whose position is given by index.
391
+ # If some or all of the items given by +tag_or_id+ do not support an insertion
392
+ # cursor then this command has no effect on them.
393
+ # See INDICES above for a description of the legal forms for index.
394
+ # Note: the insertion cursor is only displayed in an item if that item
395
+ # currently has the keyboard focus (see the widget command focus, below),
396
+ # but the cursor position may be set even when the item does not have the
397
+ # focus. This command returns an empty string.
398
+ def icursor(tag_or_id, index)
399
+ execute_only(:icursor, tag_or_id, index)
400
+ end
401
+
402
+ # This command returns a decimal string giving the numerical index within
403
+ # +tag_or_id+ corresponding to index.
404
+ # Index gives a textual description of the desired position as described in
405
+ # INDICES above.
406
+ # Text items interpret index as an index to a character, line and polygon
407
+ # items interpret it as an index to a coordinate (an x,y pair).
408
+ # The return value is guaranteed to lie between 0 and the number of
409
+ # characters, or coordinates, within the item, inclusive.
410
+ # If +tag_or_id+ refers to multiple items, then the index is processed in the
411
+ # first of these items that supports indexing operations (in display list
412
+ # order).
413
+ def index(tag_or_id, index)
414
+ execute(:index, tag_or_id, index)
415
+ end
416
+
417
+ # For each of the items given by +tag_or_id+, if the item supports text or
418
+ # coordinate, insertion then string is inserted into the item's text just
419
+ # before the character, or coordinate, whose index is +before+.
420
+ # Text items interpret +before+ as an index to a character, line and
421
+ # polygon items interpret it as an index to a coordinate (an x,y pair).
422
+ # For lines and polygons the string must be a valid coordinate sequence.
423
+ # See INDICES above for information about the forms allowed for +before+.
424
+ # This command returns an empty string.
425
+ def insert(tag_or_id, before, string)
426
+ execute(:insert, tag_or_id, before, string)
427
+ end
428
+
429
+ # Returns the current value of the configuration option for the item given
430
+ # by +tag_or_id+ whose name is option.
431
+ # This command is similar to the cget widget command except that it applies
432
+ # to a particular item rather than the widget as a whole.
433
+ # Option may have any of the values accepted by the create widget command
434
+ # when the item was created.
435
+ # If +tag_or_id+ is a tag that refers to more than one item, the first (lowest)
436
+ # such item is used.
437
+ def itemcget(tag_or_id, option)
438
+ execute(:itemcget, tag_or_id, option.to_tcl_option)
439
+ end
440
+
441
+ # This command is similar to the configure widget command except that it
442
+ # modifies item-specific options for the items given by +tag_or_id+ instead of
443
+ # modifying options for the overall canvas widget.
444
+ # If no option is specified, returns a list describing all of the available
445
+ # options for the first item given by +tag_or_id+ (see Tk_ConfigureInfo for
446
+ # information on the format of this list).
447
+ # If option is specified with no value, then the command returns a list
448
+ # describing the one named option (this list will be identical to the
449
+ # corresponding sublist of the value returned if no option is specified).
450
+ # If one or more option-value pairs are specified, then the command
451
+ # modifies the given widget option(s) to have the given value(s) in each of
452
+ # the items given by +tag_or_id+; in this case the command returns an empty
453
+ # string. The options and values are the same as those permissible in the
454
+ # create widget command when the item(s) were created; see the sections
455
+ # describing individual item types below for details on the legal options.
456
+ def itemconfigure(tag_or_id, options = None)
457
+ common_configure([:itemconfigure, tag_or_id], options)
458
+ end
459
+
460
+ # Move all of the items given by +tag_or_id+ to a new position in the display
461
+ # list just before the item given by belowThis.
462
+ # If +tag_or_id+ refers to more than one item then all are moved but the
463
+ # relative order of the moved items will not be changed.
464
+ # BelowThis is a tag or id; if it refers to more than one item then the
465
+ # first (lowest) of these items in the display list is used as the
466
+ # destination location for the moved items.
467
+ #
468
+ # Note: this command has no effect on window items.
469
+ # Window items always obscure other item types, and the stacking order of
470
+ # window items is determined by the raise and lower commands, not the raise
471
+ # and lower widget commands for canvases.
472
+ # This command returns nil.
473
+ def lower(tag_or_id, below = None)
474
+ execute_only(:lower, tag_or_id, below)
475
+ end
476
+
477
+ # Move each of the items given by +tag_or_id+ in the canvas coordinate space
478
+ # by adding +x_amount+ to the x-coordinate of each point associated with the
479
+ # item and +y_amount+ to the y-coordinate of each point associated with the
480
+ # item.
481
+ # This command returns nil.
482
+ def move(tag_or_id, x_amount, y_amount)
483
+ execute_only(:move, tag_or_id, x_amount, y_amount)
484
+ end
485
+
486
+ # Generate a Postscript representation for part or all of the canvas.
487
+ #
488
+ # If the :file option is specified then the Postscript is written to a file
489
+ # and an empty string is returned; otherwise the Postscript is returned as
490
+ # the result of the command.
491
+ # If the interpreter that owns the canvas is marked as safe, the operation
492
+ # will fail because safe interpreters are not allowed to write files.
493
+ #
494
+ # If the :channel option is specified, the argument denotes the name of a
495
+ # channel already opened for writing.
496
+ # The Postscript is written to that channel, and the channel is left open
497
+ # for further writing at the end of the operation.
498
+ #
499
+ # The Postscript is created in Encapsulated Postscript form using version
500
+ # 3.0 of the Document Structuring Conventions.
501
+ #
502
+ # Note: by default Postscript is only generated for information that
503
+ # appears in the canvas's window on the screen.
504
+ # If the canvas is freshly created it may still have its initial size of
505
+ # 1x1 pixel so nothing will appear in the Postscript.
506
+ # To get around this problem either invoke the update command to wait for
507
+ # the canvas window to reach its final size, or else use the :width and
508
+ # :height options to specify the area of the canvas to print.
509
+ #
510
+ # The +options+ argument provides additional information to control the
511
+ # generation of Postscript.
512
+ #
513
+ # The following options are supported:
514
+ #
515
+ # colormap: var_name
516
+ # var_name must be the name of an array variable that specifies a color
517
+ # mapping to use in the Postscript.
518
+ # Each element of var_name must consist of Postscript code to set a
519
+ # particular color value (e.g.
520
+ # "1.0 1.0 0.0 setrgbcolor").
521
+ # When outputting color information in the Postscript, Tk checks to see if
522
+ # there is an element of var_name with the same name as the color.
523
+ # If so, Tk uses the value of the element as the Postscript command to set
524
+ # the color.
525
+ # If this option has not been specified, or if there is no entry in
526
+ # var_name for a given color, then Tk uses the red, green, and blue
527
+ # intensities from the X color.
528
+ #
529
+ # colormode: mode
530
+ # Specifies how to output color information.
531
+ # Mode must be either color (for full color output), gray (convert all
532
+ # colors to their gray-scale equivalents) or mono (convert all colors to
533
+ # black or white).
534
+ #
535
+ # file: file_name
536
+ # Specifies the name of the file in which to write the Postscript.
537
+ # If this option is not specified then the Postscript is returned as the
538
+ # result of the command instead of being written to a file.
539
+ #
540
+ # fontmap: var_name
541
+ # var_name must be the name of an array variable that specifies a font
542
+ # mapping to use in the Postscript.
543
+ # Each element of var_name must consist of a Tcl list with two elements,
544
+ # which are the name and point size of a Postscript font.
545
+ # When outputting Postscript commands for a particular font, Tk checks to
546
+ # see if var_name contains an element with the same name as the font.
547
+ # If there is such an element, then the font information contained in that
548
+ # element is used in the Postscript.
549
+ # Otherwise Tk attempts to guess what Postscript font to use.
550
+ # Tk's guesses generally only work for well-known fonts such as Times and
551
+ # Helvetica and Courier, and only if the X font name does not omit any
552
+ # dashes up through the point size.
553
+ # For example, -*-Courier-Bold-R-Normal--*-120-* will work but
554
+ # *Courier-Bold-R-Normal*120* will not; Tk needs the dashes to parse the
555
+ # font name).
556
+ #
557
+ # height: size
558
+ # Specifies the height of the area of the canvas to print.
559
+ # Defaults to the height of the canvas window.
560
+ #
561
+ # pageanchor: anchor
562
+ # Specifies which point of the printed area of the canvas should appear
563
+ # over the positioning point on the page (which is given by the :pagex and
564
+ # :pagey options).
565
+ # For example, pageanchor: n means that the top center of the area of the
566
+ # canvas being printed (as it appears in the canvas window) should be over
567
+ # the positioning point.
568
+ # Defaults to center.
569
+ #
570
+ # pageheight: size
571
+ # Specifies that the Postscript should be scaled in both x and y so that
572
+ # the printed area is size high on the Postscript page.
573
+ # Size consists of a floating-point number followed by c for centimeters,
574
+ # i for inches, m for millimeters, or p or nothing for printer's points
575
+ # (1/72 inch).
576
+ # Defaults to the height of the printed area on the screen.
577
+ # If both :pageheight and :pagewidth are specified then the scale factor
578
+ # from :pagewidth is used (non-uniform scaling is not implemented).
579
+ #
580
+ # pagewidth: size
581
+ # Specifies that the Postscript should be scaled in both x and y so that
582
+ # the printed area is size wide on the Postscript page.
583
+ # Size has the same form as for -pageheight.
584
+ # Defaults to the width of the printed area on the screen.
585
+ # If both -pageheight and -pagewidth are specified then the scale factor
586
+ # from -pagewidth is used (non-uniform scaling is not implemented).
587
+ #
588
+ # pagex: position
589
+ # Position gives the x-coordinate of the positioning point on the
590
+ # Postscript page, using any of the forms allowed for -pageheight.
591
+ # Used in conjunction with the -pagey and -pageanchor options to determine
592
+ # where the printed area appears on the Postscript page.
593
+ # Defaults to the center of the page.
594
+ #
595
+ # pagey: position
596
+ # Position gives the y-coordinate of the positioning point on the
597
+ # Postscript page, using any of the forms allowed for -pageheight.
598
+ # Used in conjunction with the -pagex and -pageanchor options to determine
599
+ # where the printed area appears on the Postscript page.
600
+ # Defaults to the center of the page.
601
+ #
602
+ # rotate: boolean
603
+ # Boolean specifies whether the printed area is to be rotated 90 degrees.
604
+ # In non-rotated output the x-axis of the printed area runs along the
605
+ # short dimension of the page ("portrait" orientation); in rotated output
606
+ # the x-axis runs along the long dimension of the page
607
+ # ("landscape" orientation). Defaults to non-rotated.
608
+ #
609
+ # width:
610
+ # size Specifies the width of the area of the canvas to print.
611
+ # Defaults to the width of the canvas window.
612
+ #
613
+ # x: position
614
+ # Specifies the x-coordinate of the left edge of the area of the canvas
615
+ # that is to be printed, in canvas coordinates, not window coordinates.
616
+ # Defaults to the coordinate of the left edge of the window.
617
+ #
618
+ # y: position
619
+ # Specifies the y-coordinate of the top edge of the area of the canvas
620
+ # that is to be printed, in canvas coordinates, not window coordinates.
621
+ # Defaults to the coordinate of the top edge of the window.
622
+ def postscript(options = {})
623
+ execute(:postscript, options.to_tcl_options).to_s?
624
+ end
625
+
626
+ # Move all of the items given by +tag_or_id+ to a new position in the
627
+ # display list just after the item given by +above+.
628
+ # If +tag_or_id+ refers to more than one item then all are moved but the
629
+ # relative order of the moved items will not be changed.
630
+ # AboveThis is a tag or id; if it refers to more than one item then the last
631
+ # (topmost) of these items in the display list is used as the destination
632
+ # location for the moved items.
633
+ #
634
+ # Note: this command has no effect on window items.
635
+ # Window items always obscure other item types, and the stacking order of
636
+ # window items is determined by the raise and lower commands, not the raise
637
+ # and lower widget commands for canvases.
638
+ # This command returns nil.
639
+ def raise(tag_or_id, above = None)
640
+ execute_only(:raise, tag_or_id, above)
641
+ end
642
+
643
+ # Rescale all of the items given by +tag_or_id+ in canvas coordinate space.
644
+ # +x_origin+ and +y_origin+ identify the origin for the scaling operation
645
+ # and +x_scale+ and +y_scale+ identify the scale factors for x- and
646
+ # y-coordinates, respectively (a scale factor of 1.0 implies no change to
647
+ # that coordinate).
648
+ # For each of the points defining each item, the x-coordinate is adjusted to
649
+ # change the distance from +x_origin+ by a factor of +x_scale+.
650
+ # Similarly, each y-coordinate is adjusted to change the distance from
651
+ # +y_origin+ by a factor of +y_scale+.
652
+ # This command returns nil.
653
+ def scale(tag_or_id, x_origin, y_origin, x_scale, y_scale)
654
+ execute(:scale, tag_or_id, x_origin, y_origin, x_scale, y_scale)
655
+ end
656
+
657
+ # Records x and y and the canvas's current view; used in conjunction with
658
+ # later scan dragto commands.
659
+ # Typically this command is associated with a mouse button press in the
660
+ # widget and x and y are the coordinates of the mouse.
661
+ # It returns nil.
662
+ def scan_mark(x, y)
663
+ execute_only(:scan, :mark, x, y)
664
+ end
665
+
666
+ # This command computes the difference between its x and y arguments (which
667
+ # are typically mouse coordinates) and the x and y arguments to the last
668
+ # scan mark command for the widget.
669
+ # It then adjusts the view by gain times the difference in coordinates,
670
+ # where gain defaults to 10.
671
+ # This command is typically associated with mouse motion events in the
672
+ # widget, to produce the effect of dragging the canvas at high speed
673
+ # through its window.
674
+ # The return value is nil.
675
+ def scan_dragto(x, y, gain = None)
676
+ execute_only(:scan, :dragto, x, y, gain)
677
+ end
678
+
679
+ # Locate the end of the selection in +tag_or_id+ nearest to the character given
680
+ # by index, and adjust that end of the selection to be at index (i.e.
681
+ # including but not going beyond index).
682
+ # The other end of the selection is made the anchor point for future select
683
+ # to commands.
684
+ # If the selection is not currently in +tag_or_id+ then this command behaves
685
+ # the same as the select to widget command.
686
+ # Returns nil.
687
+ def select_adjust(tag_or_id, index)
688
+ execute_only(:select, :adjust, tag_or_id, index)
689
+ end
690
+
691
+ # Clear the selection if it is in this widget.
692
+ # If the selection is not in this widget then the command has no effect.
693
+ # Returns nil.
694
+ def select_clear
695
+ execute_only(:select, :clear)
696
+ end
697
+
698
+ # Set the selection anchor point for the widget to be just before the
699
+ # character given by index in the item given by +tag_or_id+.
700
+ # This command does not change the selection; it just sets the fixed end of
701
+ # the selection for future select to commands.
702
+ # Returns nil.
703
+ def select_from(tag_or_id, index)
704
+ execute(:select, :from, tag_or_id, index)
705
+ end
706
+
707
+ # Returns the id of the selected item, if the selection is in an item in
708
+ # this canvas.
709
+ # If the selection is not in this canvas then nil is returned.
710
+ def select_item
711
+ execute(:select, :item).to_s?
712
+ end
713
+
714
+ # Set the selection to consist of those characters of +tag_or_id+ between the
715
+ # selection anchor point and index.
716
+ # The new selection will include the character given by index; it will
717
+ # include the character given by the anchor point only if index is greater
718
+ # than or equal to the anchor point.
719
+ # The anchor point is determined by the most recent select adjust or select
720
+ # from command for this widget.
721
+ # If the selection anchor point for the widget is not currently in +tag_or_id+,
722
+ # then it is set to the same character given by index.
723
+ # Returns an empty string.
724
+ def select_to(tag_or_id, index)
725
+ execute(:select, :to, tag_or_id, index)
726
+ end
727
+
728
+ # Returns the type of the item given by +tag_or_id+, such as rectangle or text.
729
+ # If +tag_or_id+ refers to more than one item, then the type of the first item
730
+ # in the display list is returned.
731
+ # If +tag_or_id+ does not refer to any items at all then nil is returned.
732
+ def type(tag_or_id)
733
+ execute(:type, tag_or_id).to_sym?
734
+ end
735
+
736
+ # Returns a list containing two elements.
737
+ # Each element is a real fraction between 0 and 1; together they describe
738
+ # the horizontal span that is visible in the window.
739
+ # For example, if the first element is .2 and the second element is .6, 20%
740
+ # of the canvas's area (as defined by the -scrollregion option) is
741
+ # off-screen to the left, the middle 40% is visible in the window, and 40%
742
+ # of the canvas is off-screen to the right.
743
+ # These are the same values passed to scrollbars via the -xscrollcommand
744
+ # option.
745
+ def xview
746
+ execute(:xview).to_a(&:to_f)
747
+ end
748
+
749
+ # Adjusts the view in the window so that fraction of the total width of the
750
+ # canvas is off-screen to the left.
751
+ # Fraction must be a fraction between 0 and 1.
752
+ def xview_moveto(fraction)
753
+ execute_only(:xview, :moveto, fraction)
754
+ end
755
+
756
+ # This command shifts the view in the window left or right according to
757
+ # number and what.
758
+ # Number must be an integer.
759
+ # What must be either units or pages or an abbreviation of one of these.
760
+ # If what is units, the view adjusts left or right in units of the
761
+ # xScrollIncrement option, if it is greater than zero, or in units of
762
+ # one-tenth the window's width otherwise.
763
+ # If what is pages then the view adjusts in units of nine-tenths the
764
+ # window's width.
765
+ # If number is negative then information farther to the left becomes
766
+ # visible; if it is positive then information farther to the right becomes
767
+ # visible.
768
+ def xview_scroll(number, what)
769
+ execute_only(:xview, :scroll, number, what)
770
+ end
771
+
772
+ # Returns a list containing two elements.
773
+ # Each element is a real fraction between 0 and 1; together they describe
774
+ # the vertical span that is visible in the window.
775
+ # For example, if the first element is .6 and the second element is 1.0,
776
+ # the lowest 40% of the canvas's area (as defined by the -scrollregion
777
+ # option) is visible in the window.
778
+ # These are the same values passed to scrollbars via the -yscrollcommand
779
+ # option.
780
+ def yview
781
+ execute(:yview).to_a?(&:to_f)
782
+ end
783
+
784
+ # Adjusts the view in the window so that fraction of the canvas's area is
785
+ # off-screen to the top.
786
+ # Fraction is a fraction between 0 and 1.
787
+ def yview_moveto(fraction)
788
+ execute(:yview, :moveto, fraction)
789
+ end
790
+
791
+ # This command adjusts the view in the window up or down according to
792
+ # number and what.
793
+ # Number must be an integer.
794
+ # What must be either units or pages.
795
+ # If what is units, the view adjusts up or down in units of the
796
+ # yScrollIncrement option, if it is greater than zero, or in units of
797
+ # one-tenth the window's height otherwise.
798
+ # If what is pages then the view adjusts in units of nine-tenths the
799
+ # window's height.
800
+ # If number is negative then higher information becomes visible; if it is
801
+ # positive then lower information becomes visible.
802
+ def yview_scroll(number, what)
803
+ execute(:yview, :scroll, number, what)
804
+ end
805
+ end
806
+ end