module Tk # Canvas widgets implement structured graphics. # # A canvas displays any number of items, which may be things like rectangles, # circles, lines, and text. # Items may be manipulated (e.g. moved or re-colored) and commands may be # associated with items in much the same way that the bind command allows # commands to be bound to widgets. # For example, a particular command may be associated with the # event so that the command is invoked whenever button 1 is pressed with the # mouse cursor over an item. # This means that items in a canvas can have behaviors defined. class Canvas < Widget require "ffi-tk/widget/canvas/item.rb" require "ffi-tk/widget/canvas/arc.rb" require "ffi-tk/widget/canvas/bitmap.rb" require "ffi-tk/widget/canvas/image.rb" require "ffi-tk/widget/canvas/line.rb" require "ffi-tk/widget/canvas/oval.rb" require "ffi-tk/widget/canvas/polygon.rb" require "ffi-tk/widget/canvas/rectangle.rb" require "ffi-tk/widget/canvas/text.rb" require "ffi-tk/widget/canvas/window.rb" include Cget, Configure def self.tk_command; 'canvas'; end # For each item that meets the constraints specified by +search_spec+ and # the +args+, add +tag+ to the list of tags associated with the item if it # is not already present on that list. # It is possible that no items will satisfy the constraints given by # +search_spec+ and +args+, in which case the command has no effect. def addtag(tag, search_spec, *args) execute_only(:addtag, tag, search_spec, *args) end # Selects the item just after (above) the one given by +tag_or_id+ in the # display list. # If +tag_or_id+ denotes more than one item, then the last (topmost) of # these items in the display list is used. def addtag_above(tag, tag_or_id) execute_only(:addtag, tag, :above, tag_or_id) end # Selects all the items in the canvas. def addtag_all(tag) execute_only(:addtag, tag, :all) end # Selects the item just before (below) the one given by +tag_or_id+ in the # display list. # If +tag_or_id+ denotes more than one item, then the first (lowest) of # these items in the display list is used. def addtag_below(tag, tag_or_id) execute_only(:addtag, tag, :below, tag_or_id) end # Selects the item closest to the point given by +x+ and +y+. # If more than one item is at the same closest distance (e.g. two items # overlap the point), then the top-most of these items (the last one in the # display list) is used. # # If +halo+ is specified, then it must be a non-negative value. # Any item closer than +halo+ to the point is considered to overlap it. # # The +start+ argument may be used to step circularly through all the # closest items. # If +start+ is specified, it names an item using a tag or id (if by tag, it # selects the first item in the display list with the given tag). # Instead of selecting the topmost closest item, this form will select the # topmost closest item that is below +start+ in the display list; if no such # item exists, then the selection behaves as if the +start+ argument had not # been specified. def addtag_closest(tag, x, y, halo = None, start = None) execute_only(:addtag, tag, :closest, x, y, halo, start) end # Selects all the items completely enclosed within the rectangular region # given by +x1+, +y1+, +x2+, and +y2+. # +x1+ must be no greater then +x2+ and +y1+ must be no greater than +y2+. def addtag_enclosed(tag, x1, y1, x2, y2) execute_only(:addtag, tag, :enclosed, x1, y1, x2, y2) end # Selects all the items that overlap or are enclosed within the rectangular # region given by +x1+, +y1+, +x2+, and +y2+. # +x1+ must be no greater then +x2+ and +y1+ must be no greater than +y2+. def addtag_overlapping(tag, x1, y1, x2, y2) execute_only(:addtag, tag, :overlapping, x1, y1, x2, y2) end # Selects all the items given by +tag_or_id+. def addtag_withtag(tag, tag_or_id) execute_only(:addtag, tag, :withtag, tag_or_id) end # Returns a list with four elements giving an approximate bounding box for # all the items named by the +tags_or_ids+ argument. # The list has the form `[x1, y1, x2, y2]` such that the drawn areas of all # the named elements are within the region bounded by x1 on the left, x2 on # the right, y1 on the top, and y2 on the bottom. # The return value may overestimate the actual bounding box by a few pixels. # If no items match any of the +tags_or_ids+ argument or if the matching # items have empty bounding boxes (i.e. they have nothing to display) then # nil is returned. def bbox(*tags_or_ids) execute(:bbox, *tags_or_ids).to_a?(&:to_i) end # This method associates +command+ with all the items given by +tag_or_id+ # such that whenever the event sequence given by +sequence+ occurs for one # of the items the command will be invoked. # # This widget command is similar to the bind command except that it operates # on items in a canvas rather than entire widgets. # See the bind manual entry for complete details on the syntax of +sequence+ # and the substitutions performed on command before invoking it. # # If all arguments are specified then a new binding is created, replacing # any existing binding for the same +sequence+ and +tag_or_id+. # See [bind_append] for information of how augment an existing binding # instead of replacing it. # # In this case the return value is nil. # # If +command+ is omitted then the method returns the command associated # with +tag_or_id+ and +sequence+ (an error occurs if there is no such binding). # If both +command+ and +sequence+ are omitted then the command returns a list # of all the sequences for which bindings have been defined for +tag_or_id+. # # The only events for which bindings may be specified are those related to # the mouse and keyboard (such as Enter, Leave, ButtonPress, Motion, and # KeyPress) or virtual events. # The handling of events in canvases uses the current item defined in ITEM # IDS AND TAGS above. # Enter and Leave events trigger for an item when it becomes the current # item or ceases to be the current item; note that these events are # different than Enter and Leave events for windows. # Mouse-related events are directed to the current item, if any. # Keyboard-related events are directed to the focus item, if any (see the # focus widget command below for more on this). # If a virtual event is used in a binding, that binding can trigger only if # the virtual event is defined by an underlying mouse-related or # keyboard-related event. # It is possible for multiple bindings to match a particular event. # This could occur, for example, if one binding is associated with the # item's id and another is associated with one of the item's tags. # When this occurs, all of the matching bindings are invoked. # A binding associated with the all tag is invoked first, followed by one # binding for each of the item's tags (in order), followed by a binding # associated with the item's id. # If there are multiple matching bindings for a single tag, then only the # most specific binding is invoked. # A continue command in a binding script terminates that script, and a # break command terminates that script and skips any remaining scripts for # the event, just as for the bind command. # If bindings have been created for a canvas window using the bind command, # then they are invoked in addition to bindings created for the canvas's # items using the bind widget command. # The bindings for items will be invoked before any of the bindings for # the window as a whole. def bind(tag_or_id, sequence = None, &script) unless script if None == sequence return Tk.execute(tk_pathname, :bind, tag_or_id) else return Tk.execute(tk_pathname, :bind, tag_or_id, sequence) end end name = "#{tag_or_id}".scan(/\w+/).join('_') @events ||= {} # unregister_event(name) Event::Handler.register_custom(script) do |id| code = "%s bind %s %s { ::RubyFFI::event %d %s %s }" props = Event::Data::PROPERTIES.transpose[0].join(' ') tcl = code % [tk_pathname, tag_or_id, sequence, id, sequence, props] Tk.interp.eval(tcl) @events[name] = id end end # Given a window x-coordinate in the canvas +screenx+, this command returns # the canvas x-coordinate that is displayed at that location. # If +gridspacing+ is true, then the canvas coordinate is rounded to the # nearest multiple of gridspacing units. def canvasx(screenx, gridspacing = false) execute(:canvasx, screenx, gridspacing ? :gridspacing : None) end # Given a window y-coordinate in the canvas +screeny+ this command returns # the canvas y-coordinate that is displayed at that location. # If +gridspacing+ is true, then the canvas coordinate is rounded to the # nearest multiple of gridspacing units. def canvasy(screeny, gridspacing = false) execute(:canvasy, screeny, gridspacing ? :gridspacing : None) end # Query or modify the coordinates that define an item. # If no coordinates are specified, this command returns a list whose # elements are the coordinates of the item named by +tag_or_id+. # If coordinates are specified, then they replace the current coordinates # for the named item. # If +tag_or_id+ refers to multiple items, then the first one in the display # list is used. def coords(tag_or_id, *coord_list) if coord_list.empty? execute(:coords, tag_or_id).to_a else execute_only(:coords, tag_or_id, *coord_list.flatten) end end # Create a new item in pathName of type type. # The exact format of the arguments after type depends on type, but usually # they consist of the coordinates for one or more points, followed by # specifications for zero or more item options. # See the subsections on individual item types below for more on the syntax # of this command. # This command returns the id for the new item. def create(type, coord_list, options = {}) options = options ? options.to_tcl_options : None id = execute(:create, type, coord_list, options).to_i Item.create(self, type, id) end # Items of type arc appear on the display as arc-shaped regions. # An arc is a section of an oval delimited by two angles (specified by the # :start and :extent options) and displayed in one of several ways # (specified by the :style option). def create_arc(x1, y1, x2, y2, options = {}) create(:arc, [x1, y1, x2, y2], options) end # Items of type bitmap appear on the display as images with two colors, # foreground and background. def create_bitmap(x, y, options = {}) create(:bitmap, [x, y], options) end # Items of type image are used to display images on a canvas. def create_image(x, y, options = {}) create(:image, [x, y], options) end # Items of type line appear on the display as one or more connected line # segments or curves. # Line items support coordinate indexing operations using the methods # [dchars], [index], and [insert]. def create_line(*arguments) options, coords = arguments.partition{|arg| arg.respond_to?(:to_tcl_options) } create(:line, coords, options.first) end # Items of type oval appear as circular or oval regions on the display. # Each oval may have an outline, a fill, or both. def create_oval(x1, y1, x2, y2, options = {}) create(:oval, [x1, y1, x2, y2], options) end # Items of type polygon appear as polygonal or curved filled regions on the # display. Polygon items support coordinate indexing operations using the # methods [dchars], [index], or [insert]. def create_polygon(*arguments) options, coords = arguments.partition{|arg| arg.respond_to?(:to_tcl_options) } create(:polygon, coords, options.first) end # Items of type rectangle appear as rectangular regions on the display. # Each rectangle may have an outline, a fill, or both. def create_rectangle(x1, y1, x2, y2, options = {}) create(:rectangle, [x1, y1, x2, y2], options) end # A text item displays a string of characters on the screen in one or more # lines. Text items support indexing and selection, along with the following # text-related methods: [dchars], [focus], [icursor], [index], [insert], and # [select]. def create_text(x, y, options = {}) create(:text, [x, y], options) end # Items of type window cause a particular window to be displayed at a given # position on the canvas. def create_window(x, y, options = {}) create(:window, [x, y], options) end # For each item given by +tag_or_id+, delete the characters, or coordinates, in # the range given by +first+ and +last+, inclusive. # If some of the items given by +tag_or_id+ do not support indexing # operations then they ignore dchars. # Text items interpret +first+ and +last+ as indices to a character, line and # polygon items interpret them indices to a coordinate (an x,y pair). # Indices are described in INDICES above. # If +last+ is omitted, it defaults to +first+. # This command returns nil. def dchars(tag_or_id, first, last = None) execute_only(:dchars, tag_or_id, first, last) end # Delete the items associated with the given +tags_or_ids+, and return nil. def delete(*tags_or_ids) execute_only(:delete, *tags_or_ids) end # For each of the items given by +tag_or_id+, delete the tag given by # +tag_to_delete+ from the list of those associated with the item. # If an item does not have the tag +tag_to_delete+ then the item is # unaffected by the command. # If +tag_to_delete+ is omitted then it defaults to +tag_or_id+. # This command returns nil. def dtag(tag_or_id, tag_to_delete = None) execute_only(:dtag, tag_or_id, tag_to_delete) end # This command returns a list consisting of all the items that meet the # constraints specified by +search_command+ and +args+. # +search_command+ and +args+ have any of the forms accepted by the [addtag] # method. # The items are returned in stacking order, with the lowest item first. def find(search_command, *args) execute(:find, search_command, *args) end def find_above(tag, tag_or_id) execute(:find, tag, :above, tag_or_id) end def find_all execute(:find, :all) end def find_below(tag_or_id) execute(:find, :below, tag_or_id) end def find_closest(x, y, halo = None, start = None) execute(:find, :closest, x, y, halo, start) end def find_enclosed(x1, y1, x2, y2) execute(:find, :enclosed, x1, y1, x2, y2) end def find_overlapping(x1, y1, x2, y2) execute(:find, :overlapping, x1, y1, x2, y2) end def find_withtag(tag_or_id) execute(:find, :withtag, tag_or_id) end # Set the keyboard focus for the canvas widget to the item given by # +tag_or_id+. # If +tag_or_id+ refers to several items, then the focus is set to the # first such item in the display list that supports the insertion cursor. # If +tag_or_id+ does not refer to any items, or if none of them support the # insertion cursor, then the focus is not changed. # If +tag_or_id+ is an empty string, then the focus item is reset so that no # item has the focus. # If +tag_or_id+ is not specified then the command returns the id for the item # that currently has the focus, or an empty string if no item has the # focus. Once the focus has been set to an item, the item will display the # insertion cursor and all keyboard events will be directed to that item. # The focus item within a canvas and the focus window on the screen (set # with the focus command) are totally independent: a given item does not # actually have the input focus unless (a) its canvas is the focus window # and (b) the item is the focus item within the canvas. # In most cases it is advisable to follow the focus widget command with the # focus command to set the focus window to the canvas (if it was not there # already). def focus(tag_or_id = None) if None == tag_or_id execute(:focus) else execute_only(:focus, tag_or_id) end end # Return a list whose elements are the tags associated with the item given # by +tag_or_id+. # If +tag_or_id+ refers to more than one item, then the tags are returned from # the first such item in the display list. # If +tag_or_id+ does not refer to any items, or if the item contains no tags, # then an empty string is returned. def gettags(tag_or_id) execute(:gettags, tag_or_id).to_a end # Set the position of the insertion cursor for the item(s) given by +tag_or_id+ # to just before the character whose position is given by index. # If some or all of the items given by +tag_or_id+ do not support an insertion # cursor then this command has no effect on them. # See INDICES above for a description of the legal forms for index. # Note: the insertion cursor is only displayed in an item if that item # currently has the keyboard focus (see the widget command focus, below), # but the cursor position may be set even when the item does not have the # focus. This command returns an empty string. def icursor(tag_or_id, index) execute_only(:icursor, tag_or_id, index) end # This command returns a decimal string giving the numerical index within # +tag_or_id+ corresponding to index. # Index gives a textual description of the desired position as described in # INDICES above. # Text items interpret index as an index to a character, line and polygon # items interpret it as an index to a coordinate (an x,y pair). # The return value is guaranteed to lie between 0 and the number of # characters, or coordinates, within the item, inclusive. # If +tag_or_id+ refers to multiple items, then the index is processed in the # first of these items that supports indexing operations (in display list # order). def index(tag_or_id, index) execute(:index, tag_or_id, index) end # For each of the items given by +tag_or_id+, if the item supports text or # coordinate, insertion then string is inserted into the item's text just # before the character, or coordinate, whose index is +before+. # Text items interpret +before+ as an index to a character, line and # polygon items interpret it as an index to a coordinate (an x,y pair). # For lines and polygons the string must be a valid coordinate sequence. # See INDICES above for information about the forms allowed for +before+. # This command returns an empty string. def insert(tag_or_id, before, string) execute(:insert, tag_or_id, before, string) end # Returns the current value of the configuration option for the item given # by +tag_or_id+ whose name is option. # This command is similar to the cget widget command except that it applies # to a particular item rather than the widget as a whole. # Option may have any of the values accepted by the create widget command # when the item was created. # If +tag_or_id+ is a tag that refers to more than one item, the first (lowest) # such item is used. def itemcget(tag_or_id, option) execute(:itemcget, tag_or_id, option.to_tcl_option) end # This command is similar to the configure widget command except that it # modifies item-specific options for the items given by +tag_or_id+ instead of # modifying options for the overall canvas widget. # If no option is specified, returns a list describing all of the available # options for the first item given by +tag_or_id+ (see Tk_ConfigureInfo for # information on the format of this list). # If option is specified with no value, then the command returns a list # describing the one named option (this list will be identical to the # corresponding sublist of the value returned if no option is specified). # If one or more option-value pairs are specified, then the command # modifies the given widget option(s) to have the given value(s) in each of # the items given by +tag_or_id+; in this case the command returns an empty # string. The options and values are the same as those permissible in the # create widget command when the item(s) were created; see the sections # describing individual item types below for details on the legal options. def itemconfigure(tag_or_id, options = None) common_configure([:itemconfigure, tag_or_id], options) end # Move all of the items given by +tag_or_id+ to a new position in the display # list just before the item given by belowThis. # If +tag_or_id+ refers to more than one item then all are moved but the # relative order of the moved items will not be changed. # BelowThis is a tag or id; if it refers to more than one item then the # first (lowest) of these items in the display list is used as the # destination location for the moved items. # # Note: this command has no effect on window items. # Window items always obscure other item types, and the stacking order of # window items is determined by the raise and lower commands, not the raise # and lower widget commands for canvases. # This command returns nil. def lower(tag_or_id, below = None) execute_only(:lower, tag_or_id, below) end # Move each of the items given by +tag_or_id+ in the canvas coordinate space # by adding +x_amount+ to the x-coordinate of each point associated with the # item and +y_amount+ to the y-coordinate of each point associated with the # item. # This command returns nil. def move(tag_or_id, x_amount, y_amount) execute_only(:move, tag_or_id, x_amount, y_amount) end # Generate a Postscript representation for part or all of the canvas. # # If the :file option is specified then the Postscript is written to a file # and an empty string is returned; otherwise the Postscript is returned as # the result of the command. # If the interpreter that owns the canvas is marked as safe, the operation # will fail because safe interpreters are not allowed to write files. # # If the :channel option is specified, the argument denotes the name of a # channel already opened for writing. # The Postscript is written to that channel, and the channel is left open # for further writing at the end of the operation. # # The Postscript is created in Encapsulated Postscript form using version # 3.0 of the Document Structuring Conventions. # # Note: by default Postscript is only generated for information that # appears in the canvas's window on the screen. # If the canvas is freshly created it may still have its initial size of # 1x1 pixel so nothing will appear in the Postscript. # To get around this problem either invoke the update command to wait for # the canvas window to reach its final size, or else use the :width and # :height options to specify the area of the canvas to print. # # The +options+ argument provides additional information to control the # generation of Postscript. # # The following options are supported: # # colormap: var_name # var_name must be the name of an array variable that specifies a color # mapping to use in the Postscript. # Each element of var_name must consist of Postscript code to set a # particular color value (e.g. # "1.0 1.0 0.0 setrgbcolor"). # When outputting color information in the Postscript, Tk checks to see if # there is an element of var_name with the same name as the color. # If so, Tk uses the value of the element as the Postscript command to set # the color. # If this option has not been specified, or if there is no entry in # var_name for a given color, then Tk uses the red, green, and blue # intensities from the X color. # # colormode: mode # Specifies how to output color information. # Mode must be either color (for full color output), gray (convert all # colors to their gray-scale equivalents) or mono (convert all colors to # black or white). # # file: file_name # Specifies the name of the file in which to write the Postscript. # If this option is not specified then the Postscript is returned as the # result of the command instead of being written to a file. # # fontmap: var_name # var_name must be the name of an array variable that specifies a font # mapping to use in the Postscript. # Each element of var_name must consist of a Tcl list with two elements, # which are the name and point size of a Postscript font. # When outputting Postscript commands for a particular font, Tk checks to # see if var_name contains an element with the same name as the font. # If there is such an element, then the font information contained in that # element is used in the Postscript. # Otherwise Tk attempts to guess what Postscript font to use. # Tk's guesses generally only work for well-known fonts such as Times and # Helvetica and Courier, and only if the X font name does not omit any # dashes up through the point size. # For example, -*-Courier-Bold-R-Normal--*-120-* will work but # *Courier-Bold-R-Normal*120* will not; Tk needs the dashes to parse the # font name). # # height: size # Specifies the height of the area of the canvas to print. # Defaults to the height of the canvas window. # # pageanchor: anchor # Specifies which point of the printed area of the canvas should appear # over the positioning point on the page (which is given by the :pagex and # :pagey options). # For example, pageanchor: n means that the top center of the area of the # canvas being printed (as it appears in the canvas window) should be over # the positioning point. # Defaults to center. # # pageheight: size # Specifies that the Postscript should be scaled in both x and y so that # the printed area is size high on the Postscript page. # Size consists of a floating-point number followed by c for centimeters, # i for inches, m for millimeters, or p or nothing for printer's points # (1/72 inch). # Defaults to the height of the printed area on the screen. # If both :pageheight and :pagewidth are specified then the scale factor # from :pagewidth is used (non-uniform scaling is not implemented). # # pagewidth: size # Specifies that the Postscript should be scaled in both x and y so that # the printed area is size wide on the Postscript page. # Size has the same form as for -pageheight. # Defaults to the width of the printed area on the screen. # If both -pageheight and -pagewidth are specified then the scale factor # from -pagewidth is used (non-uniform scaling is not implemented). # # pagex: position # Position gives the x-coordinate of the positioning point on the # Postscript page, using any of the forms allowed for -pageheight. # Used in conjunction with the -pagey and -pageanchor options to determine # where the printed area appears on the Postscript page. # Defaults to the center of the page. # # pagey: position # Position gives the y-coordinate of the positioning point on the # Postscript page, using any of the forms allowed for -pageheight. # Used in conjunction with the -pagex and -pageanchor options to determine # where the printed area appears on the Postscript page. # Defaults to the center of the page. # # rotate: boolean # Boolean specifies whether the printed area is to be rotated 90 degrees. # In non-rotated output the x-axis of the printed area runs along the # short dimension of the page ("portrait" orientation); in rotated output # the x-axis runs along the long dimension of the page # ("landscape" orientation). Defaults to non-rotated. # # width: # size Specifies the width of the area of the canvas to print. # Defaults to the width of the canvas window. # # x: position # Specifies the x-coordinate of the left edge of the area of the canvas # that is to be printed, in canvas coordinates, not window coordinates. # Defaults to the coordinate of the left edge of the window. # # y: position # Specifies the y-coordinate of the top edge of the area of the canvas # that is to be printed, in canvas coordinates, not window coordinates. # Defaults to the coordinate of the top edge of the window. def postscript(options = {}) execute(:postscript, options.to_tcl_options).to_s? end # Move all of the items given by +tag_or_id+ to a new position in the # display list just after the item given by +above+. # If +tag_or_id+ refers to more than one item then all are moved but the # relative order of the moved items will not be changed. # AboveThis is a tag or id; if it refers to more than one item then the last # (topmost) of these items in the display list is used as the destination # location for the moved items. # # Note: this command has no effect on window items. # Window items always obscure other item types, and the stacking order of # window items is determined by the raise and lower commands, not the raise # and lower widget commands for canvases. # This command returns nil. def raise(tag_or_id, above = None) execute_only(:raise, tag_or_id, above) end # Rescale all of the items given by +tag_or_id+ in canvas coordinate space. # +x_origin+ and +y_origin+ identify the origin for the scaling operation # and +x_scale+ and +y_scale+ identify the scale factors for x- and # y-coordinates, respectively (a scale factor of 1.0 implies no change to # that coordinate). # For each of the points defining each item, the x-coordinate is adjusted to # change the distance from +x_origin+ by a factor of +x_scale+. # Similarly, each y-coordinate is adjusted to change the distance from # +y_origin+ by a factor of +y_scale+. # This command returns nil. def scale(tag_or_id, x_origin, y_origin, x_scale, y_scale) execute(:scale, tag_or_id, x_origin, y_origin, x_scale, y_scale) end # Records x and y and the canvas's current view; used in conjunction with # later scan dragto commands. # Typically this command is associated with a mouse button press in the # widget and x and y are the coordinates of the mouse. # It returns nil. def scan_mark(x, y) execute_only(:scan, :mark, x, y) end # This command computes the difference between its x and y arguments (which # are typically mouse coordinates) and the x and y arguments to the last # scan mark command for the widget. # It then adjusts the view by gain times the difference in coordinates, # where gain defaults to 10. # This command is typically associated with mouse motion events in the # widget, to produce the effect of dragging the canvas at high speed # through its window. # The return value is nil. def scan_dragto(x, y, gain = None) execute_only(:scan, :dragto, x, y, gain) end # Locate the end of the selection in +tag_or_id+ nearest to the character given # by index, and adjust that end of the selection to be at index (i.e. # including but not going beyond index). # The other end of the selection is made the anchor point for future select # to commands. # If the selection is not currently in +tag_or_id+ then this command behaves # the same as the select to widget command. # Returns nil. def select_adjust(tag_or_id, index) execute_only(:select, :adjust, tag_or_id, index) end # Clear the selection if it is in this widget. # If the selection is not in this widget then the command has no effect. # Returns nil. def select_clear execute_only(:select, :clear) end # Set the selection anchor point for the widget to be just before the # character given by index in the item given by +tag_or_id+. # This command does not change the selection; it just sets the fixed end of # the selection for future select to commands. # Returns nil. def select_from(tag_or_id, index) execute(:select, :from, tag_or_id, index) end # Returns the id of the selected item, if the selection is in an item in # this canvas. # If the selection is not in this canvas then nil is returned. def select_item execute(:select, :item).to_s? end # Set the selection to consist of those characters of +tag_or_id+ between the # selection anchor point and index. # The new selection will include the character given by index; it will # include the character given by the anchor point only if index is greater # than or equal to the anchor point. # The anchor point is determined by the most recent select adjust or select # from command for this widget. # If the selection anchor point for the widget is not currently in +tag_or_id+, # then it is set to the same character given by index. # Returns an empty string. def select_to(tag_or_id, index) execute(:select, :to, tag_or_id, index) end # Returns the type of the item given by +tag_or_id+, such as rectangle or text. # If +tag_or_id+ refers to more than one item, then the type of the first item # in the display list is returned. # If +tag_or_id+ does not refer to any items at all then nil is returned. def type(tag_or_id) execute(:type, tag_or_id).to_sym? end # Returns a list containing two elements. # Each element is a real fraction between 0 and 1; together they describe # the horizontal span that is visible in the window. # For example, if the first element is .2 and the second element is .6, 20% # of the canvas's area (as defined by the -scrollregion option) is # off-screen to the left, the middle 40% is visible in the window, and 40% # of the canvas is off-screen to the right. # These are the same values passed to scrollbars via the -xscrollcommand # option. def xview execute(:xview).to_a(&:to_f) end # Adjusts the view in the window so that fraction of the total width of the # canvas is off-screen to the left. # Fraction must be a fraction between 0 and 1. def xview_moveto(fraction) execute_only(:xview, :moveto, fraction) end # This command shifts the view in the window left or right according to # number and what. # Number must be an integer. # What must be either units or pages or an abbreviation of one of these. # If what is units, the view adjusts left or right in units of the # xScrollIncrement option, if it is greater than zero, or in units of # one-tenth the window's width otherwise. # If what is pages then the view adjusts in units of nine-tenths the # window's width. # If number is negative then information farther to the left becomes # visible; if it is positive then information farther to the right becomes # visible. def xview_scroll(number, what) execute_only(:xview, :scroll, number, what) end # Returns a list containing two elements. # Each element is a real fraction between 0 and 1; together they describe # the vertical span that is visible in the window. # For example, if the first element is .6 and the second element is 1.0, # the lowest 40% of the canvas's area (as defined by the -scrollregion # option) is visible in the window. # These are the same values passed to scrollbars via the -yscrollcommand # option. def yview execute(:yview) end # Adjusts the view in the window so that fraction of the canvas's area is # off-screen to the top. # Fraction is a fraction between 0 and 1. def yview_moveto(fraction) execute(:yview, :moveto, fraction) end # This command adjusts the view in the window up or down according to # number and what. # Number must be an integer. # What must be either units or pages. # If what is units, the view adjusts up or down in units of the # yScrollIncrement option, if it is greater than zero, or in units of # one-tenth the window's height otherwise. # If what is pages then the view adjusts in units of nine-tenths the # window's height. # If number is negative then higher information becomes visible; if it is # positive then lower information becomes visible. def yview_scroll(number, what) execute(:yview, :scroll, number, what) end end end