$mc create text 100 100 -text test -tag mytextTo get a little word 'test' on the canvas a position 100 100 (a but away from the left upper corner). The option '-tag' indicates we have given that text item a label which we can at any later time use to refer to it.In bwise, the first tag is seen as the block name, that is, when we make another item, let us say a circle:
# x1 y1 x2 y2 $mc create oval 50 50 150 150 -fill green -tag {mytext myoval}and make it visible under the text item by lowering it:
$mc lower myovalBecause the text and the oval have the same first tag, they are seen as part of one block by bwise, so they can be moved together, by mouse dragging. Getting current item coordinatesAfter dragging, it we want to know where the oval ended up we can inquire:
$mc coords myovalwhich will return the same type of 4-tuple as we used to create the oval with. Because the text has no unique tag of its own, we need to use the item-number returned by the canvas create command to get it's coordinates, or maybe we could ask the canvas for all items with tag mytext (both the text and the oval item) and filter out the oval id:
foreach id [$mc find withtag mytext] { if {[$mc find withtag myoval] != $id} {puts "[$mc type $id] item $id coords [$mc coords $id]"} }Or a nice set-based command would do. It could be handy to give the parts of a block common and separate tags. Analysing a bwise blockLet see what a average bwise block does with tags. I used the pro_args command (in fact as graphically accessable part of the latest procs_window upgrade) to make sure a default arguments 'newproc' procedure is called to create a block
eval [ pro_args newproc { {width {100}} {height {100}} {x {50}} {y {50}} } ] # equivalent to: # newproc {} {} in out 100 100 {} 50 50(Alternatively, the right popup menu somewhere on the canvas invoking 'newproc' would also create such a block, except it would get the default size.)The new block covers our circle-with-text, so let us raise the latter by:
$mc raise mytextNow it appears as if the circle is contained in the block, but bwise treats them as separate, for instance either can be dragged by the mouse, and appear to be separate from the other.Bwise creates the following tags for its block elements, when this type of block is created:
foreach id [tag_and Proc1] { puts "Proc1 [format "%9s" [$mc type $id]] id $id tags: {[$mc itemcget $id -tags]}" }Gives:
proc1 rectangle id 18 tags: {Proc1 newblock block} proc1 text id 19 tags: {Proc1 crb label} proc1 text id 20 tags: {Proc1 crb pinname in} proc1 line id 21 tags: {Proc1 newblock pin in typein} proc1 text id 22 tags: {Proc1 crb pinname out} proc1 line id 23 tags: {Proc1 newblock pin out typeout}For every element of the block (which I found using the tag_and command, which (also for older Tk versions) takes its argument as a list of tags, and returns all $mc canvas items with all of those tags), we see that the first tag identical, and equal to the name of the block.That makes the block displace as a whole when dragged by one of its elements, and it makes a double click generate a red bounding box containing exactly all these items.Also, it can be seen the yellow rectangle being the heart of the block has 'block' as its third tag, which enables the popup menu on it and some other things.Pins have a third tag called 'pin', to make them clickable. The second tag is for historical reasons, it should signify something like the block creator function type. Further tags are possible like for the pins they have the special meaning of pin name and type.It is usually harmless to add more tags, for whatever reason, the block create functions even have an option for this, for instance to group blocks. Adding a tag to the circle and text canvas itemsNow we could add a tag to all mytext items (the text and the oval) automatically, using:
foreach id [ $mc find withtag mytext ] { $mc itemco $id -tags [ list Proc1 [ $mc itemco $id -tags ] ] }The oval and the text have become part of the Proc1 block by tag definition, and are dragged as a whole.
lrange [ $mc coords [ tag_and {Proc1 block} ] ] 0 1Now we can place any other item set by computing the difference between the coordinates and their group upper-left coordinates.
Alternatively, one can list the upper-left base-block coords by:
foreach i [tag_and block] { puts "[block_name_fromid $i] [lrange [ $mc coords $i] 0 1]" }Note that it is possible to mess this 'database' up by having other items with the same tags as blocks.