diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | doc/canvas.n | 90 | ||||
-rw-r--r-- | generic/tkCanvas.c | 386 | ||||
-rw-r--r-- | tests/canvMoveto.test | 64 |
4 files changed, 388 insertions, 160 deletions
@@ -1,3 +1,11 @@ +2008-10-01 Donal K. Fellows <dkf@users.sf.net> + + TIP #236 IMPLEMENTATION + + * doc/canvas.n, generic/tkCanvas.c (CanvasWidgetCmd) + * tests/canvMoveto.test: Added 'moveto' subcommand to canvases to + allow items to be easily moved to a particular place. + 2008-09-23 Donal K. Fellows <dkf@users.sf.net> * doc/listbox.n (SEE ALSO): Redirected this to ttk::treeview(n) which diff --git a/doc/canvas.n b/doc/canvas.n index 9019ea7..c8a689f 100644 --- a/doc/canvas.n +++ b/doc/canvas.n @@ -6,7 +6,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: canvas.n,v 1.36 2008/09/23 13:36:37 dkf Exp $ +'\" RCS: @(#) $Id: canvas.n,v 1.37 2008/09/30 23:54:46 dkf Exp $ '\" .so man.macros .TH canvas n 8.3 Tk "Tk Built-In Commands" @@ -256,6 +256,7 @@ and the selection. Their indices are supposed to be even always, because coordinates always appear in pairs. .TP 10 \fInumber\fR +. A decimal number giving the position of the desired character within the text item. 0 refers to the first character, 1 to the next character, and @@ -270,23 +271,28 @@ the length until the result is between zero and the length, inclusive. .TP 10 \fBend\fR +. Refers to the character or coordinate just after the last one in the item (same as the number of characters or coordinates in the item). .TP 10 \fBinsert\fR +. Refers to the character just before which the insertion cursor is drawn in this item. Not valid for lines and polygons. .TP 10 \fBsel.first\fR +. Refers to the first selected character in the item. If the selection is not in this item then this form is illegal. .TP 10 \fBsel.last\fR +. Refers to the last selected character in the item. If the selection is not in this item then this form is illegal. .TP 10 \fB@\fIx,y\fR +. Refers to the character or coordinate at the point given by \fIx\fR and \fIy\fR, where \fIx\fR and \fIy\fR are specified in the coordinate system of the canvas. @@ -346,6 +352,7 @@ determine the exact behavior of the command. The following widget commands are possible for canvas widgets: .TP \fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg arg ...\fR? +. For each item that meets the constraints specified by \fIsearchSpec\fR and the \fIarg\fRs, add \fItag\fR to the list of tags associated with the item if it @@ -359,21 +366,25 @@ forms: .RS .TP \fBabove \fItagOrId\fR +. Selects the item just after (above) the one given by \fItagOrId\fR in the display list. If \fItagOrId\fR denotes more than one item, then the last (topmost) of these items in the display list is used. .TP \fBall\fR +. Selects all the items in the canvas. .TP \fBbelow \fItagOrId\fR +. Selects the item just before (below) the one given by \fItagOrId\fR in the display list. If \fItagOrId\fR denotes more than one item, then the first (lowest) of these items in the display list is used. .TP \fBclosest \fIx y \fR?\fIhalo\fR? ?\fIstart\fR? +. Selects the item closest to the point given by \fIx\fR and \fIy\fR. 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 @@ -393,12 +404,14 @@ the display list; if no such item exists, then the selection behaves as if the \fIstart\fR argument had not been specified. .TP \fBenclosed\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR +. Selects all the items completely enclosed within the rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR. \fIX1\fR must be no greater then \fIx2\fR and \fIy1\fR must be no greater than \fIy2\fR. .TP \fBoverlapping\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR +. Selects all the items that overlap or are enclosed within the rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR. @@ -406,10 +419,12 @@ and \fIy2\fR. no greater than \fIy2\fR. .TP \fBwithtag \fItagOrId\fR +. Selects all the items given by \fItagOrId\fR. .RE .TP \fIpathName \fBbbox \fItagOrId\fR ?\fItagOrId tagOrId ...\fR? +. Returns a list with four elements giving an approximate bounding box for all the items named by the \fItagOrId\fR arguments. The list has the form @@ -426,6 +441,7 @@ to display) then an empty string is returned. .TP \fIpathName \fBbind \fItagOrId\fR ?\fIsequence\fR? ?\fIcommand\fR? +. This command associates \fIcommand\fR with all the items given by \fItagOrId\fR such that whenever the event sequence given by \fIsequence\fR occurs for one of the items the command will @@ -486,24 +502,28 @@ for the window as a whole. .RE .TP \fIpathName \fBcanvasx \fIscreenx\fR ?\fIgridspacing\fR? +. Given a window x-coordinate in the canvas \fIscreenx\fR, this command returns the canvas x-coordinate that is displayed at that location. If \fIgridspacing\fR is specified, then the canvas coordinate is rounded to the nearest multiple of \fIgridspacing\fR units. .TP \fIpathName \fBcanvasy \fIscreeny\fR ?\fIgridspacing\fR? +. Given a window y-coordinate in the canvas \fIscreeny\fR this command returns the canvas y-coordinate that is displayed at that location. If \fIgridspacing\fR is specified, then the canvas coordinate is rounded to the nearest multiple of \fIgridspacing\fR units. .TP \fIpathName \fBcget\fR \fIoption\fR +. Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBcanvas\fR command. .TP \fIpathName \fBconfigure ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR? +. Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for @@ -520,6 +540,7 @@ command. \fIpathName\fR \fBcoords \fItagOrId \fR?\fIx0 y0 ...\fR? .TP \fIpathName\fR \fBcoords \fItagOrId \fR?\fIcoordList\fR? +. 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 @@ -532,6 +553,7 @@ the first one in the display list is used. \fIpathName \fBcreate \fItype x y \fR?\fIx y ...\fR? ?\fIoption value ...\fR? .TP \fIpathName \fBcreate \fItype coordList \fR?\fIoption value ...\fR? +. Create a new item in \fIpathName\fR of type \fItype\fR. The exact format of the arguments after \fBtype\fR depends on \fBtype\fR, but usually they consist of the coordinates for @@ -542,6 +564,7 @@ on the syntax of this command. This command returns the id for the new item. .TP \fIpathName \fBdchars \fItagOrId first \fR?\fIlast\fR? +. For each item given by \fItagOrId\fR, delete the characters, or coordinates, in the range given by \fIfirst\fR and \fIlast\fR, inclusive. If some of the items given by \fItagOrId\fR do not support @@ -553,10 +576,12 @@ If \fIlast\fR is omitted, it defaults to \fIfirst\fR. This command returns an empty string. .TP \fIpathName \fBdelete \fR?\fItagOrId tagOrId ...\fR? +. Delete each of the items given by each \fItagOrId\fR, and return an empty string. .TP \fIpathName \fBdtag \fItagOrId \fR?\fItagToDelete\fR? +. For each of the items given by \fItagOrId\fR, delete the tag given by \fItagToDelete\fR from the list of those associated with the item. @@ -566,6 +591,7 @@ If \fItagToDelete\fR is omitted then it defaults to \fItagOrId\fR. This command returns an empty string. .TP \fIpathName \fBfind \fIsearchCommand \fR?\fIarg arg ...\fR? +. This command returns a list consisting of all the items that meet the constraints specified by \fIsearchCommand\fR and \fIarg\fR's. @@ -574,6 +600,7 @@ accepted by the \fBaddtag\fR command. The items are returned in stacking order, with the lowest item first. .TP \fIpathName \fBfocus \fR?\fItagOrId\fR? +. Set the keyboard focus for the canvas widget to the item given by \fItagOrId\fR. If \fItagOrId\fR refers to several items, then the focus is set @@ -602,6 +629,7 @@ the canvas (if it was not there already). .RE .TP \fIpathName \fBgettags\fR \fItagOrId\fR +. Return a list whose elements are the tags associated with the item given by \fItagOrId\fR. If \fItagOrId\fR refers to more than one item, then the tags @@ -610,6 +638,7 @@ If \fItagOrId\fR does not refer to any items, or if the item contains no tags, then an empty string is returned. .TP \fIpathName \fBicursor \fItagOrId index\fR +. Set the position of the insertion cursor for the item(s) given by \fItagOrId\fR to just before the character whose position is given by \fIindex\fR. If some or all of the items given by \fItagOrId\fR do not support @@ -623,6 +652,7 @@ be set even when the item does not have the focus. This command returns an empty string. .TP \fIpathName \fBindex \fItagOrId index\fR +. This command returns a decimal string giving the numerical index within \fItagOrId\fR corresponding to \fIindex\fR. \fIIndex\fR gives a textual description of the desired position @@ -636,6 +666,7 @@ is processed in the first of these items that supports indexing operations (in display list order). .TP \fIpathName \fBinsert \fItagOrId beforeThis string\fR +. For each of the items given by \fItagOrId\fR, if the item supports text or coordinate, insertion then \fIstring\fR is inserted into the item's text just before the character, or coordinate, whose index is \fIbeforeThis\fR. @@ -648,6 +679,7 @@ for \fIbeforeThis\fR. This command returns an empty string. .TP \fIpathName \fBitemcget\fR \fItagOrId\fR \fIoption\fR +. Returns the current value of the configuration option for the item given by \fItagOrId\fR whose name is \fIoption\fR. This command is similar to the \fBcget\fR widget command except that @@ -658,6 +690,7 @@ If \fItagOrId\fR is a tag that refers to more than one item, the first (lowest) such item is used. .TP \fIpathName \fBitemconfigure \fItagOrId\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR? +. This command is similar to the \fBconfigure\fR widget command except that it modifies item-specific options for the items given by \fItagOrId\fR instead of modifying options for the overall @@ -679,6 +712,7 @@ see the sections describing individual item types below for details on the legal options. .TP \fIpathName \fBlower \fItagOrId \fR?\fIbelowThis\fR? +. Move all of the items given by \fItagOrId\fR to a new position in the display list just before the item given by \fIbelowThis\fR. If \fItagOrId\fR refers to more than one item then all are moved @@ -693,13 +727,27 @@ determined by the \fBraise\fR and \fBlower\fR commands, not the This command returns an empty string. .TP \fIpathName \fBmove \fItagOrId xAmount yAmount\fR +. Move each of the items given by \fItagOrId\fR in the canvas coordinate space by adding \fIxAmount\fR to the x-coordinate of each point associated with the item and \fIyAmount\fR to the y-coordinate of each point associated with the item. This command returns an empty string. .TP +\fIpathName \fBmoveto \fItagOrId xPos yPos +.VS 8.6 +Move the items given by \fItagOrId\fR in the canvas coordinate +space so that the first coordinate pair of the bottommost item with +tag \fItagOrId\fR is located at +position (\fIxPos\fR,\fIyPos\fR). \fIxPos\fR and \fIyPos\fR may be +the empty string, in which case the corresponding coordinate +will be unchanged. All items matching +\fItagOrId\fR remain in the same positions relative to each other. +This command returns an empty string. +.VE 8.6 +.TP \fIpathName \fBpostscript \fR?\fIoption value option value ...\fR? +. Generate a Postscript representation for part or all of the canvas. If the \fB\-file\fR option is specified then the Postscript is written to a file and an empty string is returned; otherwise the Postscript @@ -725,6 +773,7 @@ options are supported: .RS .TP \fB\-colormap \fIvarName\fR +. \fIVarName\fR must be the name of an array variable that specifies a color mapping to use in the Postscript. Each element of \fIvarName\fR must consist of Postscript @@ -740,17 +789,20 @@ in \fIvarName\fR for a given color, then Tk uses the red, green, and blue intensities from the X color. .TP \fB\-colormode \fImode\fR +. Specifies how to output color information. \fIMode\fR must be either \fBcolor\fR (for full color output), \fBgray\fR (convert all colors to their gray-scale equivalents) or \fBmono\fR (convert all colors to black or white). .TP \fB\-file \fIfileName\fR +. 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. .TP \fB\-fontmap \fIvarName\fR +. \fIVarName\fR must be the name of an array variable that specifies a font mapping to use in the Postscript. Each element of \fIvarName\fR must consist of a Tcl list with @@ -769,10 +821,12 @@ For example, \fB\-*\-Courier\-Bold\-R\-Normal\-\-*\-120\-*\fR will work but parse the font name). .TP \fB\-height \fIsize\fR +. Specifies the height of the area of the canvas to print. Defaults to the height of the canvas window. .TP \fB\-pageanchor \fIanchor\fR +. Specifies which point of the printed area of the canvas should appear over the positioning point on the page (which is given by the \fB\-pagex\fR and \fB\-pagey\fR options). @@ -781,6 +835,7 @@ area of the canvas being printed (as it appears in the canvas window) should be over the positioning point. Defaults to \fBcenter\fR. .TP \fB\-pageheight \fIsize\fR +. Specifies that the Postscript should be scaled in both x and y so that the printed area is \fIsize\fR high on the Postscript page. \fISize\fR consists of a floating-point number followed by @@ -792,6 +847,7 @@ the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling is not implemented). .TP \fB\-pagewidth \fIsize\fR +. Specifies that the Postscript should be scaled in both x and y so that the printed area is \fIsize\fR wide on the Postscript page. \fISize\fR has the same form as for \fB\-pageheight\fR. @@ -801,6 +857,7 @@ the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling is not implemented). .TP \fB\-pagex \fIposition\fR +. \fIPosition\fR gives the x-coordinate of the positioning point on the Postscript page, using any of the forms allowed for \fB\-pageheight\fR. Used in conjunction with the \fB\-pagey\fR and \fB\-pageanchor\fR options @@ -808,6 +865,7 @@ to determine where the printed area appears on the Postscript page. Defaults to the center of the page. .TP \fB\-pagey \fIposition\fR +. \fIPosition\fR gives the y-coordinate of the positioning point on the Postscript page, using any of the forms allowed for \fB\-pageheight\fR. Used in conjunction with the \fB\-pagex\fR and \fB\-pageanchor\fR options @@ -815,6 +873,7 @@ to determine where the printed area appears on the Postscript page. Defaults to the center of the page. .TP \fB\-rotate \fIboolean\fR +. \fIBoolean\fR specifies whether the printed area is to be rotated 90 degrees. In non-rotated output the x-axis of the printed area runs along @@ -825,16 +884,19 @@ in rotated output the x-axis runs along the long dimension of the page Defaults to non-rotated. .TP \fB\-width \fIsize\fR +. Specifies the width of the area of the canvas to print. Defaults to the width of the canvas window. .TP \fB\-x \fIposition\fR +. 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. .TP \fB\-y \fIposition\fR +. 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. @@ -842,6 +904,7 @@ Defaults to the coordinate of the top edge of the window. .RE .TP \fIpathName \fBraise \fItagOrId \fR?\fIaboveThis\fR? +. Move all of the items given by \fItagOrId\fR to a new position in the display list just after the item given by \fIaboveThis\fR. If \fItagOrId\fR refers to more than one item then all are moved @@ -856,6 +919,7 @@ determined by the \fBraise\fR and \fBlower\fR commands, not the This command returns an empty string. .TP \fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR +. Rescale all of the items given by \fItagOrId\fR in canvas coordinate space. \fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling @@ -870,18 +934,21 @@ from \fIyOrigin\fR by a factor of \fIyScale\fR. This command returns an empty string. .TP \fIpathName \fBscan\fR \fIoption args\fR +. This command is used to implement scanning on canvases. It has two forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBscan mark \fIx y\fR +. Records \fIx\fR and \fIy\fR and the canvas's current view; used in conjunction with later \fBscan dragto\fR commands. Typically this command is associated with a mouse button press in the widget and \fIx\fR and \fIy\fR are the coordinates of the mouse. It returns an empty string. .TP -\fIpathName \fBscan dragto \fIx y ?gain?\fR. +\fIpathName \fBscan dragto \fIx y ?gain?\fR +. This command computes the difference between its \fIx\fR and \fIy\fR arguments (which are typically mouse coordinates) and the \fIx\fR and \fIy\fR arguments to the last \fBscan mark\fR command for the widget. @@ -894,6 +961,7 @@ value is an empty string. .RE .TP \fIpathName \fBselect \fIoption\fR ?\fItagOrId arg\fR? +. Manipulates the selection in one of several ways, depending on \fIoption\fR. The command may take any of the forms described below. @@ -906,6 +974,7 @@ within \fItagOrId\fR, as described in \fBINDICES\fR above. .RS .TP \fIpathName \fBselect adjust \fItagOrId index\fR +. Locate the end of the selection in \fItagOrId\fR nearest to the character given by \fIindex\fR, and adjust that end of the selection to be at \fIindex\fR (i.e. including @@ -918,12 +987,14 @@ command. Returns an empty string. .TP \fIpathName \fBselect clear\fR +. Clear the selection if it is in this widget. If the selection is not in this widget then the command has no effect. Returns an empty string. .TP \fIpathName \fBselect from \fItagOrId index\fR +. Set the selection anchor point for the widget to be just before the character given by \fIindex\fR in the item given by \fItagOrId\fR. @@ -933,12 +1004,14 @@ commands. Returns an empty string. .TP \fIpathName \fBselect item\fR +. 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 an empty string is returned. .TP \fIpathName \fBselect to \fItagOrId index\fR +. Set the selection to consist of those characters of \fItagOrId\fR between the selection anchor point and \fIindex\fR. @@ -954,6 +1027,7 @@ Returns an empty string. .RE .TP \fIpathName \fBtype\fI tagOrId\fR +. Returns the type of the item given by \fItagOrId\fR, such as \fBrectangle\fR or \fBtext\fR. If \fItagOrId\fR refers to more than one item, then the type @@ -962,12 +1036,14 @@ If \fItagOrId\fR does not refer to any items at all then an empty string is returned. .TP \fIpathName \fBxview \fR?\fIargs\fR? +. This command is used to query and change the horizontal position of the information displayed in the canvas's window. It can take any of the following forms: .RS .TP \fIpathName \fBxview\fR +. 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. @@ -979,11 +1055,13 @@ These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR option. .TP \fIpathName \fBxview moveto\fI fraction\fR +. Adjusts the view in the window so that \fIfraction\fR of the total width of the canvas is off-screen to the left. \fIFraction\fR must be a fraction between 0 and 1. .TP \fIpathName \fBxview scroll \fInumber what\fR +. This command shifts the view in the window left or right according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. @@ -1000,12 +1078,14 @@ becomes visible. .RE .TP \fIpathName \fByview \fI?args\fR? +. This command is used to query and change the vertical position of the information displayed in the canvas's window. It can take any of the following forms: .RS .TP \fIpathName \fByview\fR +. 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. @@ -1016,11 +1096,13 @@ These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR option. .TP \fIpathName \fByview moveto\fI fraction\fR +. Adjusts the view in the window so that \fIfraction\fR of the canvas's area is off-screen to the top. \fIFraction\fR is a fraction between 0 and 1. .TP \fIpathName \fByview scroll \fInumber what\fR +. This command adjusts the view in the window up or down according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. @@ -1784,6 +1866,7 @@ The following standard options are supported by window items: The following extra options are supported for window items: .TP \fB\-anchor \fIanchorPos\fR +. \fIAnchorPos\fR tells how to position the window relative to the positioning point for the item; it may have any of the forms accepted by \fBTk_GetAnchor\fR. For example, if \fIanchorPos\fR @@ -1793,6 +1876,7 @@ its top center point is at the positioning point. This option defaults to \fBcenter\fR. .TP \fB\-height \fIpixels\fR +. Specifies the height to assign to the item's window. \fIPixels\fR may have any of the forms described in the \fBCOORDINATES\fR section above. @@ -1800,6 +1884,7 @@ If this option is not specified, or if it is specified as an empty string, then the window is given whatever height it requests internally. .TP \fB\-width \fIpixels\fR +. Specifies the width to assign to the item's window. \fIPixels\fR may have any of the forms described in the \fBCOORDINATES\fR section above. @@ -1807,6 +1892,7 @@ If this option is not specified, or if it is specified as an empty string, then the window is given whatever width it requests internally. .TP \fB\-window \fIpathName\fR +. Specifies the window to associate with this item. The window specified by \fIpathName\fR must either be a child of the canvas widget or a child of some ancestor of the canvas widget. diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c index e44c6fc..bc37043 100644 --- a/generic/tkCanvas.c +++ b/generic/tkCanvas.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvas.c,v 1.50 2008/07/23 23:24:21 nijtmans Exp $ + * RCS: @(#) $Id: tkCanvas.c,v 1.51 2008/09/30 23:54:46 dkf Exp $ */ /* #define USE_OLD_TAG_SEARCH 1 */ @@ -105,7 +105,7 @@ typedef struct TagSearch { static Tk_CustomOption stateOption = { (Tk_OptionParseProc *) TkStateParseProc, TkStatePrintProc, - (ClientData) NULL /* only "normal" and "disabled" */ + (ClientData) NULL /* Only "normal" and "disabled". */ }; static Tk_CustomOption offsetOption = { @@ -215,8 +215,9 @@ static Tk_ConfigSpec configSpecs[] = { * protected by typeListMutex. */ -static Tk_ItemType *typeList = NULL; /* NULL means initialization hasn't - * been done yet. */ +static Tk_ItemType *typeList = NULL; + /* NULL means initialization hasn't been done + * yet. */ TCL_DECLARE_MUTEX(typeListMutex) #ifndef USE_OLD_TAG_SEARCH @@ -547,9 +548,9 @@ CanvasWidgetCmd( "create", "dchars", "delete", "dtag", "find", "focus", "gettags", "icursor", "index", "insert", "itemcget", "itemconfigure", - "lower", "move", "postscript", "raise", - "scale", "scan", "select", "type", - "xview", "yview", + "lower", "move", "moveto", "postscript", + "raise", "scale", "scan", "select", + "type", "xview", "yview", NULL }; enum options { @@ -558,9 +559,9 @@ CanvasWidgetCmd( CANV_CREATE, CANV_DCHARS, CANV_DELETE, CANV_DTAG, CANV_FIND, CANV_FOCUS, CANV_GETTAGS, CANV_ICURSOR, CANV_INDEX, CANV_INSERT, CANV_ITEMCGET, CANV_ITEMCONFIGURE, - CANV_LOWER, CANV_MOVE, CANV_POSTSCRIPT,CANV_RAISE, - CANV_SCALE, CANV_SCAN, CANV_SELECT, CANV_TYPE, - CANV_XVIEW, CANV_YVIEW + CANV_LOWER, CANV_MOVE, CANV_MOVETO, CANV_POSTSCRIPT, + CANV_RAISE, CANV_SCALE, CANV_SCAN, CANV_SELECT, + CANV_TYPE, CANV_XVIEW, CANV_YVIEW }; if (objc < 2) { @@ -584,7 +585,8 @@ CanvasWidgetCmd( #ifdef USE_OLD_TAG_SEARCH result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3); #else /* USE_OLD_TAG_SEARCH */ - result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3, &searchPtr); + result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3, + &searchPtr); #endif /* USE_OLD_TAG_SEARCH */ break; @@ -772,8 +774,8 @@ CanvasWidgetCmd( object, Tcl_GetString(objv[3])); Tcl_ResetResult(interp); Tcl_AppendResult(interp, "requested illegal events; ", - "only key, button, motion, enter, leave, and virtual ", - "events may be used", NULL); + "only key, button, motion, enter, leave, and virtual", + " events may be used", NULL); result = TCL_ERROR; goto done; } @@ -817,13 +819,14 @@ CanvasWidgetCmd( result = TCL_ERROR; goto done; } - if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], &x) != TCL_OK) { + if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], + &x) != TCL_OK) { result = TCL_ERROR; goto done; } if (objc == 4) { - if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3], - &grid) != TCL_OK) { + if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[3], &grid) != TCL_OK) { result = TCL_ERROR; goto done; } @@ -845,7 +848,8 @@ CanvasWidgetCmd( result = TCL_ERROR; goto done; } - if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], &y) != TCL_OK) { + if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], + &y) != TCL_OK) { result = TCL_ERROR; goto done; } @@ -897,12 +901,12 @@ CanvasWidgetCmd( } if (itemPtr->typePtr->coordProc != NULL) { if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = (*itemPtr->typePtr->coordProc)(interp, + result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3); } else { const char **args = TkGetStringsFromObjs(objc-3, objv+3); - result = (*itemPtr->typePtr->coordProc)(interp, + result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr, itemPtr, objc-3, (Tcl_Obj **) args); if (args != NULL) { @@ -932,26 +936,35 @@ CanvasWidgetCmd( } arg = Tcl_GetStringFromObj(objv[2], &length); c = arg[0]; + + /* + * Lock because the list of types is a global resource that could be + * updated by another thread. That's fairly unlikely, but not + * impossible. + */ + Tcl_MutexLock(&typeListMutex); - for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr) { + for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr){ if ((c == typePtr->name[0]) - && (strncmp(arg, typePtr->name, (unsigned)length) == 0)) { + && (!strncmp(arg, typePtr->name, (unsigned)length))) { if (matchPtr != NULL) { Tcl_MutexUnlock(&typeListMutex); badType: Tcl_AppendResult(interp, - "unknown or ambiguous item type \"",arg,"\"",NULL); + "unknown or ambiguous item type \"", arg, "\"", + NULL); result = TCL_ERROR; goto done; } matchPtr = typePtr; } } + /* - * Can unlock now because we no longer look at the fields of - * the matched item type that are potentially modified by - * other threads. + * Can unlock now because we no longer look at the fields of the + * matched item type that are potentially modified by other threads. */ + Tcl_MutexUnlock(&typeListMutex); if (matchPtr == NULL) { goto badType; @@ -960,6 +973,7 @@ CanvasWidgetCmd( /* * Allow more specific error return. */ + Tcl_WrongNumArgs(interp, 3, objv, "coords ?arg ...?"); result = TCL_ERROR; goto done; @@ -975,12 +989,12 @@ CanvasWidgetCmd( itemPtr->state = TK_STATE_NULL; itemPtr->redraw_flags = 0; if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr, + result = typePtr->createProc(interp, (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3); } else { const char **args = TkGetStringsFromObjs(objc-3, objv+3); - result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr, + result = typePtr->createProc(interp, (Tk_Canvas) canvasPtr, itemPtr, objc-3, (Tcl_Obj **) args); if (args != NULL) { ckfree((char *) args); @@ -1031,8 +1045,8 @@ CanvasWidgetCmd( &first); } else { result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]), - &first); + (Tk_Canvas) canvasPtr, itemPtr, + Tcl_GetString(objv[3]), &first); } if (result != TCL_OK) { goto done; @@ -1064,8 +1078,8 @@ CanvasWidgetCmd( x1 = itemPtr->x1; y1 = itemPtr->y1; x2 = itemPtr->x2; y2 = itemPtr->y2; itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; - (*itemPtr->typePtr->dCharsProc)((Tk_Canvas) canvasPtr, - itemPtr, first, last); + itemPtr->typePtr->dCharsProc((Tk_Canvas) canvasPtr, itemPtr, + first, last); if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) { Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, x1, y1, x2, y2); @@ -1086,7 +1100,7 @@ CanvasWidgetCmd( Tk_DeleteAllBindings(canvasPtr->bindingTable, (ClientData) itemPtr); } - (*itemPtr->typePtr->deleteProc)((Tk_Canvas) canvasPtr, itemPtr, + itemPtr->typePtr->deleteProc((Tk_Canvas) canvasPtr, itemPtr, canvasPtr->display); if (itemPtr->tagPtr != itemPtr->staticTagSpace) { ckfree((char *) itemPtr->tagPtr); @@ -1238,13 +1252,13 @@ CanvasWidgetCmd( &index); } else { result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]), - &index); + (Tk_Canvas) canvasPtr, itemPtr, + Tcl_GetString(objv[3]), &index); } if (result != TCL_OK) { goto done; } - (*itemPtr->typePtr->icursorProc)((Tk_Canvas) canvasPtr, itemPtr, + itemPtr->typePtr->icursorProc((Tk_Canvas) canvasPtr, itemPtr, index); if ((itemPtr == canvasPtr->textInfo.focusItemPtr) && (canvasPtr->textInfo.cursorOn)) { @@ -1274,10 +1288,10 @@ CanvasWidgetCmd( goto done; } if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr, + result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas)canvasPtr, itemPtr, (char *) objv[3], &index); } else { - result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr, + result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas)canvasPtr, itemPtr, Tcl_GetString(objv[3]), &index); } if (result != TCL_OK) { @@ -1307,8 +1321,8 @@ CanvasWidgetCmd( &beforeThis); } else { result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]), - &beforeThis); + (Tk_Canvas) canvasPtr, itemPtr, + Tcl_GetString(objv[3]), &beforeThis); } if (result != TCL_OK) { goto done; @@ -1325,11 +1339,11 @@ CanvasWidgetCmd( x2 = itemPtr->x2; y2 = itemPtr->y2; itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - (*itemPtr->typePtr->insertProc)((Tk_Canvas) canvasPtr, - itemPtr, beforeThis, (char *) objv[4]); + itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr, + beforeThis, (char *) objv[4]); } else { - (*itemPtr->typePtr->insertProc)((Tk_Canvas) canvasPtr, - itemPtr, beforeThis, Tcl_GetString(objv[4])); + itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr, + beforeThis, Tcl_GetString(objv[4])); } if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) { Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, @@ -1371,13 +1385,13 @@ CanvasWidgetCmd( } else { EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = (*itemPtr->typePtr->configProc)(interp, + result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3, TK_CONFIG_ARGV_ONLY); } else { const char **args = TkGetStringsFromObjs(objc-3, objv+3); - result = (*itemPtr->typePtr->configProc)(interp, + result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr, itemPtr, objc-3, (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY); if (args != NULL) { @@ -1439,13 +1453,77 @@ CanvasWidgetCmd( } FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); - (void) (*itemPtr->typePtr->translateProc)((Tk_Canvas) canvasPtr, - itemPtr, xAmount, yAmount); + itemPtr->typePtr->translateProc((Tk_Canvas) canvasPtr, itemPtr, + xAmount, yAmount); EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); canvasPtr->flags |= REPICK_NEEDED; } break; } + case CANV_MOVETO: { + int xBlank, yBlank; + double xAmount, yAmount; + double oldX = 0, oldY = 0, newX, newY; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "tagOrId x y"); + result = TCL_ERROR; + goto done; + } + + xBlank = 0; + if (Tcl_GetString(objv[3])[0] == '\0') { + xBlank = 1; + } else if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[3], &newX) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + + yBlank = 0; + if (Tcl_GetString(objv[4])[0] == '\0') { + yBlank = 1; + } else if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[4], &newY) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + + FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done); + if (itemPtr != NULL) { + oldX = itemPtr->x1; + oldY = itemPtr->y1; + + /* + * Calculate the displacement. + */ + + if (xBlank) { + xAmount = 0; + } else { + xAmount = newX - oldX; + } + + if (yBlank) { + yAmount = 0; + } else { + yAmount = newY - oldY; + } + + /* + * Move the object(s). + */ + + FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { + EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + itemPtr->typePtr->translateProc((Tk_Canvas) canvasPtr, + itemPtr, xAmount, yAmount); + EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + canvasPtr->flags |= REPICK_NEEDED; + } + } + break; + } case CANV_POSTSCRIPT: { const char **args = TkGetStringsFromObjs(objc, objv); @@ -1493,7 +1571,8 @@ CanvasWidgetCmd( double xOrigin, yOrigin, xScale, yScale; if (objc != 7) { - Tcl_WrongNumArgs(interp, 2, objv, "tagOrId xOrigin yOrigin xScale yScale"); + Tcl_WrongNumArgs(interp, 2, objv, + "tagOrId xOrigin yOrigin xScale yScale"); result = TCL_ERROR; goto done; } @@ -1501,8 +1580,8 @@ CanvasWidgetCmd( objv[3], &xOrigin) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[4], &yOrigin) != TCL_OK) - || (Tcl_GetDoubleFromObj(interp, objv[5], &xScale) != TCL_OK) - || (Tcl_GetDoubleFromObj(interp, objv[6], &yScale) != TCL_OK)) { + || (Tcl_GetDoubleFromObj(interp, objv[5], &xScale)!=TCL_OK) + || (Tcl_GetDoubleFromObj(interp, objv[6], &yScale)!=TCL_OK)) { result = TCL_ERROR; goto done; } @@ -1513,8 +1592,8 @@ CanvasWidgetCmd( } FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); - (void) (*itemPtr->typePtr->scaleProc)((Tk_Canvas) canvasPtr, - itemPtr, xOrigin, yOrigin, xScale, yScale); + itemPtr->typePtr->scaleProc((Tk_Canvas) canvasPtr, itemPtr, + xOrigin, yOrigin, xScale, yScale); EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); canvasPtr->flags |= REPICK_NEEDED; } @@ -1600,8 +1679,8 @@ CanvasWidgetCmd( &index); } else { result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[4]), - &index); + (Tk_Canvas) canvasPtr, itemPtr, + Tcl_GetString(objv[4]), &index); } if (result != TCL_OK) { goto done; @@ -1688,8 +1767,8 @@ CanvasWidgetCmd( break; case CANV_XVIEW: { int count, type; - int newX = 0; /* Initialization needed only to prevent - * gcc warnings. */ + int newX = 0; /* Initialization needed only to prevent gcc + * warnings. */ double fraction; if (objc == 2) { @@ -1735,8 +1814,8 @@ CanvasWidgetCmd( } case CANV_YVIEW: { int count, type; - int newY = 0; /* Initialization needed only to prevent - * gcc warnings. */ + int newY = 0; /* Initialization needed only to prevent gcc + * warnings. */ double fraction; if (objc == 2) { @@ -1826,7 +1905,7 @@ DestroyCanvas( for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = canvasPtr->firstItemPtr) { canvasPtr->firstItemPtr = itemPtr->nextPtr; - (*itemPtr->typePtr->deleteProc)((Tk_Canvas) canvasPtr, itemPtr, + itemPtr->typePtr->deleteProc((Tk_Canvas) canvasPtr, itemPtr, canvasPtr->display); if (itemPtr->tagPtr != itemPtr->staticTagSpace) { ckfree((char *) itemPtr->tagPtr); @@ -2034,7 +2113,7 @@ CanvasWorldChanged( itemPtr = canvasPtr->firstItemPtr; for ( ; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - result = (*itemPtr->typePtr->configProc)(canvasPtr->interp, + result = itemPtr->typePtr->configProc(canvasPtr->interp, (Tk_Canvas) canvasPtr, itemPtr, 0, NULL, TK_CONFIG_ARGV_ONLY); if (result != TCL_OK) { @@ -2224,7 +2303,7 @@ DisplayCanvas( canvasPtr->canvas_state == TK_STATE_HIDDEN)) { continue; } - (*itemPtr->typePtr->displayProc)((Tk_Canvas) canvasPtr, itemPtr, + itemPtr->typePtr->displayProc((Tk_Canvas) canvasPtr, itemPtr, canvasPtr->display, pixmap, screenX1, screenY1, width, height); } @@ -2374,8 +2453,8 @@ CanvasEventProc( for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { if (itemPtr->typePtr->alwaysRedraw & 1) { - (*itemPtr->typePtr->displayProc)((Tk_Canvas) canvasPtr, - itemPtr, canvasPtr->display, None, 0, 0, 0, 0); + itemPtr->typePtr->displayProc((Tk_Canvas) canvasPtr, itemPtr, + canvasPtr->display, None, 0, 0, 0, 0); } } } @@ -2514,8 +2593,8 @@ EventuallyRedrawItem( if ((itemPtr->x1 >= itemPtr->x2) || (itemPtr->y1 >= itemPtr->y2) || (itemPtr->x2 < canvasPtr->xOrigin) || (itemPtr->y2 < canvasPtr->yOrigin) || - (itemPtr->x1 >= canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)) || - (itemPtr->y1 >= canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin))) { + (itemPtr->x1 >= canvasPtr->xOrigin+Tk_Width(canvasPtr->tkwin)) || + (itemPtr->y1 >= canvasPtr->yOrigin+Tk_Height(canvasPtr->tkwin))) { if (!(itemPtr->typePtr->alwaysRedraw & 1)) { return; } @@ -2738,7 +2817,7 @@ StartTagSearch( if ((itemPtr == NULL) || (itemPtr->id != id) || (lastPtr == NULL) || (lastPtr->nextPtr != itemPtr)) { dispPtr->numSlowSearches++; - entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id); + entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char*) id); if (entryPtr != NULL) { itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr); lastPtr = itemPtr->prevPtr; @@ -3076,6 +3155,7 @@ TagSearchScan( * kept forever, but this should be thought of as a cache rather than as a * memory leak. */ + searchPtr->expr->uid = Tk_GetUid(tag); /* @@ -3087,8 +3167,8 @@ TagSearchScan( } /* - * Pre-scan tag for at least one unquoted "&&" "||" "^" "!" - * if not found then use string as simple tag + * Pre-scan tag for at least one unquoted "&&" "||" "^" "!"; if not found + * then use string as simple tag. */ for (i = 0; i < searchPtr->stringLength ; i++) { @@ -3165,7 +3245,7 @@ TagSearchScan( static void TagSearchDestroy( - TagSearch *searchPtr) /* Record describing tag search */ + TagSearch *searchPtr) /* Record describing tag search. */ { if (searchPtr) { TagSearchExprDestroy(searchPtr->expr); @@ -3196,15 +3276,15 @@ TagSearchDestroy( static int TagSearchScanExpr( Tcl_Interp *interp, /* Current interpreter. */ - TagSearch *searchPtr, /* Search data */ - TagSearchExpr *expr) /* compiled expression result */ + TagSearch *searchPtr, /* Search data. */ + TagSearchExpr *expr) /* Compiled expression result. */ { int looking_for_tag; /* When true, scanner expects next char(s) to - * be a tag, else operand expected */ - int found_tag; /* One or more tags found */ - int found_endquote; /* For quoted tag string parsing */ - int negate_result; /* Pending negation of next tag value */ - char *tag; /* Tag from tag expression string */ + * be a tag, else operand expected. */ + int found_tag; /* One or more tags found. */ + int found_endquote; /* For quoted tag string parsing. */ + int negate_result; /* Pending negation of next tag value. */ + char *tag; /* Tag from tag expression string. */ char c; SearchUids *searchUids; /* Collection of uids for basic search * expression terms. */ @@ -3219,36 +3299,33 @@ TagSearchScanExpr( if (expr->allocated == expr->index) { expr->allocated += 15; if (expr->uids) { - expr->uids = (Tk_Uid *) - ckrealloc((char *)(expr->uids), - (expr->allocated)*sizeof(Tk_Uid)); + expr->uids = (Tk_Uid *) ckrealloc((char *) expr->uids, + expr->allocated * sizeof(Tk_Uid)); } else { expr->uids = (Tk_Uid *) - ckalloc((expr->allocated)*sizeof(Tk_Uid)); + ckalloc(expr->allocated * sizeof(Tk_Uid)); } } if (looking_for_tag) { - switch (c) { - case ' ': /* ignore unquoted whitespace */ + case ' ': /* Ignore unquoted whitespace */ case '\t': case '\n': case '\r': break; - case '!': /* negate next tag or subexpr */ + case '!': /* Negate next tag or subexpr */ if (looking_for_tag > 1) { Tcl_AppendResult(interp, - "Too many '!' in tag search expression", - NULL); + "Too many '!' in tag search expression", NULL); return TCL_ERROR; } looking_for_tag++; negate_result = 1; break; - case '(': /* scan (negated) subexpr recursively */ + case '(': /* Scan (negated) subexpr recursively */ if (negate_result) { expr->uids[expr->index++] = searchUids->negparenUid; negate_result = 0; @@ -3267,7 +3344,7 @@ TagSearchScanExpr( found_tag = 1; break; - case '"': /* quoted tag string */ + case '"': /* Quoted tag string */ if (negate_result) { expr->uids[expr->index++] = searchUids->negtagvalUid; negate_result = 0; @@ -3287,13 +3364,13 @@ TagSearchScanExpr( } *tag++ = c; } - if (! found_endquote) { + if (!found_endquote) { Tcl_AppendResult(interp, "Missing endquote in tag search expression", NULL); return TCL_ERROR; } - if (! (tag - searchPtr->rewritebuffer)) { + if (!(tag - searchPtr->rewritebuffer)) { Tcl_AppendResult(interp, "Null quoted tag string in tag search expression", NULL); @@ -3306,7 +3383,7 @@ TagSearchScanExpr( found_tag = 1; break; - case '&': /* illegal chars when looking for tag */ + case '&': /* Illegal chars when looking for tag */ case '|': case '^': case ')': @@ -3315,7 +3392,7 @@ TagSearchScanExpr( NULL); return TCL_ERROR; - default: /* unquoted tag string */ + default: /* Unquoted tag string */ if (negate_result) { expr->uids[expr->index++] = searchUids->negtagvalUid; negate_result = 0; @@ -3362,48 +3439,46 @@ TagSearchScanExpr( found_tag = 1; } - } else { /* ! looking_for_tag */ + } else { /* ! looking_for_tag */ switch (c) { - case ' ': /* ignore whitespace */ + case ' ': /* Ignore whitespace */ case '\t': case '\n': case '\r': break; - case '&': /* AND operator */ + case '&': /* AND operator */ c = searchPtr->string[searchPtr->stringIndex++]; if (c != '&') { Tcl_AppendResult(interp, - "Singleton '&' in tag search expression", - NULL); + "Singleton '&' in tag search expression", NULL); return TCL_ERROR; } expr->uids[expr->index++] = searchUids->andUid; looking_for_tag = 1; break; - case '|': /* OR operator */ + case '|': /* OR operator */ c = searchPtr->string[searchPtr->stringIndex++]; if (c != '|') { Tcl_AppendResult(interp, - "Singleton '|' in tag search expression", - NULL); + "Singleton '|' in tag search expression", NULL); return TCL_ERROR; } expr->uids[expr->index++] = searchUids->orUid; looking_for_tag = 1; break; - case '^' : /* XOR operator */ + case '^': /* XOR operator */ expr->uids[expr->index++] = searchUids->xorUid; looking_for_tag = 1; break; - case ')' : /* end subexpression */ + case ')': /* End subexpression */ expr->uids[expr->index++] = searchUids->endparenUid; goto breakwhile; - default: /* syntax error */ + default: /* syntax error */ Tcl_AppendResult(interp, "Invalid boolean operator in tag search expression", NULL); @@ -3413,7 +3488,7 @@ TagSearchScanExpr( } breakwhile: - if (found_tag && ! looking_for_tag) { + if (found_tag && !looking_for_tag) { return TCL_OK; } Tcl_AppendResult(interp, "Missing tag in tag search expression", NULL); @@ -3453,7 +3528,7 @@ TagSearchEvalExpr( * expression terms. */ searchUids = GetStaticUids(); - result = 0; /* just to keep the compiler quiet */ + result = 0; /* Just to keep the compiler quiet. */ negate_result = 0; looking_for_tag = 1; @@ -3488,7 +3563,7 @@ TagSearchEvalExpr( result = 0; /* - * set result 1 if tag is found in item's tags + * set result 1 if tag is found in item's tags. */ for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags; @@ -3501,23 +3576,19 @@ TagSearchEvalExpr( } else if (uid == searchUids->parenUid) { /* - * Evaluate subexpressions with recursion + * Evaluate subexpressions with recursion. */ result = TagSearchEvalExpr(expr, itemPtr); } else if (uid == searchUids->negparenUid) { - negate_result = ! negate_result; + negate_result = !negate_result; /* - * Evaluate subexpressions with recursion + * Evaluate subexpressions with recursion. */ result = TagSearchEvalExpr(expr, itemPtr); -/* - * } else { - * assert(0); - */ } if (negate_result) { result = ! result; @@ -3566,16 +3637,12 @@ TagSearchEvalExpr( } else if (uid == searchUids->endparenUid) { return result; -/* - * } else { - * assert(0); - */ } looking_for_tag = 1; } } /* - * assert(! looking_for_tag); + * assert(!looking_for_tag); */ return result; } @@ -3664,7 +3731,7 @@ TagSearchFirst( uid = searchPtr->expr->uid; for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr; - itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) { + itemPtr != NULL; lastPtr=itemPtr, itemPtr=itemPtr->nextPtr) { for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags; count > 0; tagPtr++, count--) { if (*tagPtr == uid) { @@ -3675,13 +3742,12 @@ TagSearchFirst( } } } else { - /* * None of the above. Search for an item matching the tag expression. */ for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr; - itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) { + itemPtr != NULL; lastPtr=itemPtr, itemPtr=itemPtr->nextPtr) { searchPtr->expr->index = 0; if (TagSearchEvalExpr(searchPtr->expr, itemPtr)) { searchPtr->lastPtr = lastPtr; @@ -3767,7 +3833,7 @@ TagSearchNext( */ uid = searchPtr->expr->uid; - for (; itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) { + for (; itemPtr != NULL; lastPtr=itemPtr, itemPtr=itemPtr->nextPtr) { for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags; count > 0; tagPtr++, count--) { if (*tagPtr == uid) { @@ -3996,14 +4062,15 @@ FindItems( Tcl_WrongNumArgs(interp, first+1, objv, "x y ?halo? ?start?"); return TCL_ERROR; } - if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[first+1], - &coords[0]) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, - (Tk_Canvas) canvasPtr, objv[first+2], &coords[1]) != TCL_OK)) { + if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[first+1], &coords[0]) != TCL_OK + || Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[first+2], &coords[1]) != TCL_OK) { return TCL_ERROR; } if (objc > first+3) { - if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[first+3], - &halo) != TCL_OK) { + if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[first+3], &halo) != TCL_OK) { return TCL_ERROR; } if (halo < 0.0) { @@ -4045,7 +4112,7 @@ FindItems( if (itemPtr == NULL) { return TCL_OK; } - closestDist = (*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr, + closestDist = itemPtr->typePtr->pointProc((Tk_Canvas) canvasPtr, itemPtr, coords) - halo; if (closestDist < 0.0) { closestDist = 0.0; @@ -4088,7 +4155,7 @@ FindItems( || (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) { continue; } - newDist = (*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr, + newDist = itemPtr->typePtr->pointProc((Tk_Canvas) canvasPtr, itemPtr, coords) - halo; if (newDist < 0.0) { newDist = 0.0; @@ -4169,11 +4236,11 @@ FindArea( if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[0], &rect[0]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[1], + || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[1], &rect[1]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[2], + || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[2], &rect[2]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3], + || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[3], &rect[3]) != TCL_OK)) { return TCL_ERROR; } @@ -4189,21 +4256,22 @@ FindArea( * item-specific code except for items that are close. */ - x1 = (int) (rect[0]-1.0); - y1 = (int) (rect[1]-1.0); - x2 = (int) (rect[2]+1.0); - y2 = (int) (rect[3]+1.0); + x1 = (int) (rect[0] - 1.0); + y1 = (int) (rect[1] - 1.0); + x2 = (int) (rect[2] + 1.0); + y2 = (int) (rect[3] + 1.0); for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - if (itemPtr->state == TK_STATE_HIDDEN || (itemPtr->state == TK_STATE_NULL && - canvasPtr->canvas_state == TK_STATE_HIDDEN)) { + if (itemPtr->state == TK_STATE_HIDDEN || + (itemPtr->state == TK_STATE_NULL + && canvasPtr->canvas_state == TK_STATE_HIDDEN)) { continue; } if ((itemPtr->x1 >= x2) || (itemPtr->x2 <= x1) || (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) { continue; } - if ((*itemPtr->typePtr->areaProc)((Tk_Canvas) canvasPtr, itemPtr, rect) + if (itemPtr->typePtr->areaProc((Tk_Canvas) canvasPtr, itemPtr, rect) >= enclosed) { DoItem(interp, itemPtr, uid); } @@ -4369,7 +4437,7 @@ CanvasBindProc( * current item while buttons are down. */ - if ((eventPtr->type == ButtonPress) || (eventPtr->type == ButtonRelease)) { + if (eventPtr->type == ButtonPress || eventPtr->type == ButtonRelease) { int mask; switch (eventPtr->xbutton.button) { @@ -4520,11 +4588,11 @@ PickCurrentItem( canvasPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root; canvasPtr->pickEvent.xcrossing.mode = NotifyNormal; canvasPtr->pickEvent.xcrossing.detail = NotifyNonlinear; - canvasPtr->pickEvent.xcrossing.same_screen - = eventPtr->xmotion.same_screen; + canvasPtr->pickEvent.xcrossing.same_screen = + eventPtr->xmotion.same_screen; canvasPtr->pickEvent.xcrossing.focus = False; canvasPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state; - } else { + } else { canvasPtr->pickEvent = *eventPtr; } } @@ -4556,7 +4624,7 @@ PickCurrentItem( if ((canvasPtr->newCurrentPtr == canvasPtr->currentItemPtr) && !(canvasPtr->flags & LEFT_GRABBED_ITEM)) { /* - * Nothing to do: the current item hasn't changed. + * Nothing to do: the current item hasn't changed. */ return; @@ -4619,7 +4687,7 @@ PickCurrentItem( * deleted. */ } - if ((canvasPtr->newCurrentPtr != canvasPtr->currentItemPtr) && buttonDown) { + if ((canvasPtr->newCurrentPtr!=canvasPtr->currentItemPtr) && buttonDown) { canvasPtr->flags |= LEFT_GRABBED_ITEM; return; } @@ -4636,7 +4704,7 @@ PickCurrentItem( if (prevItemPtr != NULL && prevItemPtr != canvasPtr->currentItemPtr && (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) { EventuallyRedrawItem((Tk_Canvas) canvasPtr, prevItemPtr); - (*prevItemPtr->typePtr->configProc)(canvasPtr->interp, + prevItemPtr->typePtr->configProc(canvasPtr->interp, (Tk_Canvas) canvasPtr, prevItemPtr, 0, NULL, TK_CONFIG_ARGV_ONLY); } @@ -4650,7 +4718,7 @@ PickCurrentItem( #endif /* USE_OLD_TAG_SEA */ if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT && prevItemPtr != canvasPtr->currentItemPtr)) { - (*canvasPtr->currentItemPtr->typePtr->configProc)(canvasPtr->interp, + canvasPtr->currentItemPtr->typePtr->configProc(canvasPtr->interp, (Tk_Canvas) canvasPtr, canvasPtr->currentItemPtr, 0, NULL, TK_CONFIG_ARGV_ONLY); EventuallyRedrawItem((Tk_Canvas) canvasPtr, @@ -4700,8 +4768,10 @@ CanvasFindClosest( bestPtr = NULL; for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - if (itemPtr->state == TK_STATE_HIDDEN || itemPtr->state==TK_STATE_DISABLED || - (itemPtr->state == TK_STATE_NULL && (canvasPtr->canvas_state == TK_STATE_HIDDEN || + if (itemPtr->state == TK_STATE_HIDDEN || + itemPtr->state==TK_STATE_DISABLED || + (itemPtr->state == TK_STATE_NULL && + (canvasPtr->canvas_state == TK_STATE_HIDDEN || canvasPtr->canvas_state == TK_STATE_DISABLED))) { continue; } @@ -4709,8 +4779,8 @@ CanvasFindClosest( || (itemPtr->y1 > y2) || (itemPtr->y2 < y1)) { continue; } - if ((*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr, - itemPtr, coords) <= canvasPtr->closeEnough) { + if (itemPtr->typePtr->pointProc((Tk_Canvas) canvasPtr, itemPtr, + coords) <= canvasPtr->closeEnough) { bestPtr = itemPtr; } } @@ -5042,7 +5112,7 @@ CanvasFetchSelection( if (canvasPtr->textInfo.selItemPtr->typePtr->selectionProc == NULL) { return -1; } - return (*canvasPtr->textInfo.selItemPtr->typePtr->selectionProc)( + return canvasPtr->textInfo.selItemPtr->typePtr->selectionProc( (Tk_Canvas) canvasPtr, canvasPtr->textInfo.selItemPtr, offset, buffer, maxBytes); } @@ -5221,7 +5291,7 @@ CanvasUpdateScrollbars( Tcl_Obj *fractions = ScrollFractions(xOrigin + inset, xOrigin + width - inset, scrollX1, scrollX2); - result = Tcl_VarEval(interp, xScrollCmd, " ", Tcl_GetString(fractions), + result = Tcl_VarEval(interp, xScrollCmd," ",Tcl_GetString(fractions), NULL); Tcl_DecrRefCount(fractions); if (result != TCL_OK) { @@ -5235,7 +5305,7 @@ CanvasUpdateScrollbars( Tcl_Obj *fractions = ScrollFractions(yOrigin + inset, yOrigin + height - inset, scrollY1, scrollY2); - result = Tcl_VarEval(interp, yScrollCmd, " ", Tcl_GetString(fractions), + result = Tcl_VarEval(interp, yScrollCmd," ",Tcl_GetString(fractions), NULL); Tcl_DecrRefCount(fractions); if (result != TCL_OK) { @@ -5310,11 +5380,11 @@ CanvasSetOrigin( * Adjust the origin if necessary to keep as much as possible of the * canvas in the view. The variables left, right, etc. keep track of how * much extra space there is on each side of the view before it will stick - * out past the scroll region. If one side sticks out past the edge of - * the scroll region, adjust the view to bring that side back to the edge - * of the scrollregion (but don't move it so much that the other side - * sticks out now). If scroll increments are in effect, be sure to adjust - * only by full increments. + * out past the scroll region. If one side sticks out past the edge of the + * scroll region, adjust the view to bring that side back to the edge of + * the scrollregion (but don't move it so much that the other side sticks + * out now). If scroll increments are in effect, be sure to adjust only by + * full increments. */ if ((canvasPtr->confine) && (canvasPtr->regionString != NULL)) { diff --git a/tests/canvMoveto.test b/tests/canvMoveto.test new file mode 100644 index 0000000..255df99 --- /dev/null +++ b/tests/canvMoveto.test @@ -0,0 +1,64 @@ +# This file is a Tcl script to test out the canvas "moveto" command. +# +# this file is derived from canvRect.test, which contains the +# following copyright notices: +# +# Copyright (c) 1994-1996 Sun Microsystems, Inc. +# Copyright (c) 1998-1999 by Scriptics Corporation. +# All rights reserved. +# +# RCS: @(#) $Id: canvMoveto.test,v 1.1 2008/09/30 23:54:46 dkf Exp $ + +package require tcltest 2.1 +eval tcltest::configure $argv +tcltest::loadTestedCommands + +canvas .c -width 400 -height 300 -bd 2 -relief sunken +pack .c +bind .c <1> { + puts "button down at (%x,%y)" +} +update + +.c create rectangle 20 20 80 80 -tag {test rect1} +.c create rectangle 40 40 90 100 -tag {test rect2} + +test canvMoveto-1.1 {Bad args handling for "moveto" command} { + list [catch {.c moveto test} msg] $msg +} {1 {wrong # args: should be ".c moveto tagOrId x y"}} +test canvMoveto-1.2 {Bad args handling for "moveto" command} { + list [catch {.c moveto rect} msg] $msg +} {1 {wrong # args: should be ".c moveto tagOrId x y"}} +test canvMoveto-1.3 {Bad args handling for "moveto" command} { + list [catch {.c moveto test 12} msg] $msg +} {1 {wrong # args: should be ".c moveto tagOrId x y"}} +test canvMoveto-1.4 {Bad args handling for "moveto" command} { + list [catch {.c moveto test 12 y} msg] $msg +} {1 {bad screen distance "y"}} +test canvMoveto-1.5 {Bad args handling for "moveto" command} { + list [catch {.c moveto test 12 20 -anchor} msg] $msg +} {1 {wrong # args: should be ".c moveto tagOrId x y"}} + +test canvMoveto-2.1 {Canvas "moveto" command coordinates} { + .c moveto test 200 150 + .c bbox test +} {200 150 272 232} + + +test canvMoveto-3.1 {Canvas "moveto" command blank y coordinate} { + .c moveto test 200 150 + .c moveto test 150 {} + .c bbox test +} {150 150 222 232} + +test canvMoveto-3.2 {Canvas "moveto" command blank x coordinate} { + .c moveto test 200 150 + .c moveto test {} 200 + .c bbox test +} {200 200 272 282} + +.c delete withtag all + +# cleanup +cleanupTests +return |