Version 0 of BWise block coordinate extraction

Updated 2004-05-10 09:51:23

TV

Considering bwise is not a full blown, user-perfect application, with all bells and whisles, but that it alternatively is a interesting enough application and OK use of various Tcl/Tk facilities, a short page on how to get coordinates from blocks on a Bwise canvas, using the default assumptions on block composition.

Bwise makes direct use of th Tk canvas, which already existed a decade ago, and as it is uses only very backward compatible commands.

The way to deal with (graphical) canvas items and their grouping is the use of tags, which is a list of identifiers attached to each item.

I assume BWise has been started, with a console window open to type interactive commands (either using 'console show' on windows, or source-ing the console for Unix, or using tkcon ). In bwise, for one window only, the variable mc points at .mw.c usually as the active bwise canvas widget. So one could

   $mc create text 100 100 -text test -tag mytext

To 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, lets 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 myoval

Because 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.

After dragging, it we want to know where the oval ended up we can inquire:

   $mc coords myoval

which 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 seperate tags.

Let 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 lets raise the latter by:

   $mc raise mytext

Now it appears as if the circle is contained in the block, but bwise treats them as seperate, for instance either can be dragged by the mouse, and appear to be seperate 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.