Menu

Home

George A. Howlett

The BLT Toolkit is an extension to Tcl and Tk. It adds new commands and widgets to the Tcl interpreter. Included widgets are 2D graph, barchart, stripchart, tab notebook, and tree viewer.


Project Members:


Discussion

  • Edward Sternin

    Edward Sternin - 2020-02-11

    Since I am lucky enough to be the first Wiki contributor, I must begin by expressing a universal, I am sure, love and admiration for this amazing, outstanding bit of code craftsmanship.

    Thanks, George A. Howlett! You have created an indispensable tool.


    BLT 2.4z has been the mainstay of most Linux distributions for a while and, unfortunately, the recent changes to the code here have not yet made it through to the distribution channels. I wanted to make my code run under either the 2.x series or under the current 3.0 (4.0? in Readme) versions if you downloaded/compiled/installed that from this sourceforge location.

    These are some of the tricks I had to use:

    if { [catch {set BLTversion [package require BLT]}] } {
        puts stderr "BLT package is missing, maybe `sudo apt-get install blt`\n"; exit 1
    } else {
      if { ![package vsatisfies $BLTversion 3] } {set BLT3 0} else {set BLT3 1}
      }
    
    if { [info exists BLTversion] } {
      if { [catch namespace import ::blt::*] } { ;# in BLT3 blt::scale conflicts with tcl/tk scale
        namespace import ::blt::graph
        namespace import ::blt::vector
        namespace import ::blt::marker
        namespace import ::blt::element
        }
      }
    

    Then, later on I can use the BLT3 flag to identify the incompatible bits of code:

    if {$BLT3} {
        if { [info exists x] } { vector destroy x }  ; vector create x  -length $size
        if { [info exists y] } { vector destroy y } ; vector create y -length $size
         } else {;# BLT 2.x allowed to re-create existing vectors
        vector create x($size) y($size)
        }
    
      if {$BLT3} {
        $g axis configure x -title $xlabel -grid yes
        $g axis configure y -title $ylabel -grid yes
      } else {
        $g axis configure x -title $xlabel
        $g axis configure y -title $ylabel
        $g grid configure -mapx x -mapy y
        }
    
    # Blt_ZoomStack enables the mouse-button manipulation of a stack
    # of zoom levels. One can change min/max values on axes directly, 
    # and then mix these manually set zoom levels into the stack. 
    # 
    proc AddZoomStack { } {
      global BLT3 g
      if {$BLT3} {variable ::blt::Graph::_private} else {global zoomInfo}
      set cmd {}
      foreach margin { xaxis yaxis x2axis y2axis } {
        foreach axis [$g $margin use] {
          set min [$g axis cget $axis -min]; set max [$g axis cget $axis -max]
          set c [list $g axis configure $axis -min $min -max $max]
          append cmd "$c\n"
          }
        }
      if {$BLT3} { set _private($g,stack) [linsert $_private($g,stack) 0 $cmd]
      } else {     set zoomInfo($g,stack) [linsert $zoomInfo($g,stack) 0 $cmd] }
      }
    
     

    Last edit: Edward Sternin 2020-02-11
  • Edward Sternin

    Edward Sternin - 2022-07-06

    BLT v.3 significantly changed the syntax of the vector command. Since a lot of places are still running v.2.47z, trying to write universal code requires accommodations like these:

    proc newVector { name len } {
      # BLT 2.x allowed to re-create existing vectors,
      # this is necessary in BLT 3 but will also work in BLT 2.x
      global BLT3 $name
      if { [info exists ${name}] } { vector destroy ${name} }
      if {$len != "" && $len > 0} { 
        if {$BLT3} {
          vector create ${name} -length $len
          # BLT 3 initializes to NaN, restore BLT 2.x behaviour of initializing to 0.0
          set ${name}(:) 0.0
          }\
        else {
          vector create ${name}($len)
          }
        }\
      else {
        vector create ${name}
        }
      } 
    
    # take care of the BLT v.2.x syntax: "vector create x y(5) z..."
    proc vectorsCreate { lv } {
      foreach v $lv {
        set v_name [lindex [split $v ()] 0]
        set v_len  [lindex [split $v ()] 1]
        newVector $v_name $v_len
        }
      }
    

    With the above, both newVector x 5 and vectorsCreate {y(3) z t(0)} (which is a slight modification of what in v.2.47z would have been vector create y(3) z t(0)) work fine under all versions of BLT.

     
    • George A. Howlett

      I believe the syntax

      blt::vector /arrayName/(/len/)

      works the same in both versions.

      Since the create operation has switches in 3.x, the old syntax of

      blt::vector create /arrayName/(/len/) ... * * could not be cleanly maintained.  [The idea in 2.x was to have the
      vector look like a data type instead of a command.]

      **
      You would still have to set the values to 0.0 to replicate the 2.x behavior.

      --gah

      On 7/6/22 18:27, Edward Sternin wrote:

      BLT v.3 significantly changed the syntax of the |vector| command.
      Since a lot of places are still running v.2.47z, trying to write
      universal code requires accommodations like these:

      |procnewVector{namelen}{#BLT2.xallowedtore-createexistingvectors,#thisisnecessaryinBLT3butwillalsoworkinBLT2.xglobalBLT3$nameif{[infoexists${name}]}{vectordestroy${name}}if{$len!=""&&$len>0}{if{$BLT3}{vectorcreate${name}-length$len#BLT3initializestoNaN,restoreBLT2.xbehaviourofinitializingto0.0set${name}(:)0.0}\else{vectorcreate${name}($len)}}\else{vectorcreate${name}}}#takecareoftheBLTv.2.xsyntax:"vector
      create x y(5)
      z..."procvectorsCreate{lv}{foreachv$lv{setv_name[lindex[split$v()]0]setv_len[lindex[split$v()]1]newVector$v_name$v_len}}|

      With the above, both |newVector x 5| and |vectorsCreate {y(3) z t(0)}|
      (which is a slight modification of what in v.2.47z would have been
      |vector create y(3) z t(0)|) work fine under all versions of BLT.


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/blt/wiki/Home/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
      • Edward Sternin

        Edward Sternin - 2022-07-12

        Sorry, @ghowlett, I may have been unclear. It's the loss of ability to declare multiple vectors on one line that represents a discontinuity in syntax:

        $ bltsh30 
        % blt::vector create x(5) t w
        unknown switch "t"
        The following switches are available:
           -variable varName
           -command command
           -watchunset bool
           -flush bool
           -length length
        

        although I just noticed that there is in v.2.5.3 from blt-dev an option:
        vector configure -oldcreate bool which may be doing what I had in mind:

        The configure operation sets the default options used in creating vectors: ... The -oldcreate enable the creation shortcut: vector vec1 vec2 ...

        However, this seems to not have been included in 3.0, so it's probably one of the non-canonical changes made in a fork of the BLT. It does seem like a reasonable approach, though I still think that simply preserving the old flexible syntax would be my first choice.
        Even in the new syntax, I think the multiple-vector option could be maintained: all switches begin with a -, so in

        vector create x -length 5 t w
        

        it's pretty clear that vectors t and w would have a zero length. Or one could use

        vector create x -length 5 -- t w
        
         
        • George A. Howlett

          I think it was me that was probably unclear.

          If you don't use the "create" keyword, then you can still create
          multiple vectors with the same command.  This works in both 2.x and 3.x.

          bltsh30
          % blt::vector x(30) y(30) z(30)

          I'm not 100% clear as to why syntactical compatibility between  2.x and
          3.x is needed. Nor why the vectors need to created in a single command.

          Is this because the TCL code making the call can't be changed?

          [It wasn't my goal in 3.x to be 100% backward compatible with 2.x
          syntax.  The addition of switches to the create operation superseded
          maintaining the old syntax.]

          I don't know anything about 2.5.3.

          --gah

          On 7/11/22 19:20, Edward Sternin wrote:

          Sorry, @ghowlett https://sourceforge.net/u/ghowlett/, I may have
          been unclear. It's the loss of ability to declare multiple vectors
          on one line that represents a discontinuity in syntax:

          |$ bltsh30 % blt::vector create x(5) t w unknown switch "t" The
          following switches are available: -variable varName -command command
          -watchunset bool -flush bool -length length |

          although I just noticed that there is in v.2.5.3
          https://manpages.debian.org/jessie/blt-dev/blt::vector.3tcl from
          |blt-dev| an option:
          |vector configure -oldcreate bool| which may be doing what I had in mind:

          The configure operation sets the default options used in creating
          vectors: ... The -oldcreate enable the creation shortcut: vector
          vec1 vec2 ...
          

          However, this seems to not have been included in 3.0, so it's probably
          one of the non-canonical changes made in a fork of the BLT. It does
          seem like a reasonable approach, though I still think that simply
          preserving the old flexible syntax would be my first choice.
          Even in the new syntax, I think the multiple-vector option could be
          maintained: all switches begin with a |-|, so in

          |vector create x -length 5 t w |

          it's pretty clear that vectors |t| and |w| would have a zero length.
          Or one could use

          |vector create x -length 5 -- t w |

          Sent from sourceforge.net because you indicated interest in
          https://sourceforge.net/p/blt/wiki/Home/

          To unsubscribe from further messages, please visit
          https://sourceforge.net/auth/subscriptions/

           
          • Edward Sternin

            Edward Sternin - 2022-07-12

            Oh, I see! Vectors get created even without create! This might be good enough.

            I'm not 100% clear as to why syntactical compatibility between 2.x and
            3.x is needed. Nor why the vectors need to created in a single command.

            Is this because the TCL code making the call can't be changed?

            The reason for my initiating this compatibility discussion is this: if I want to write a code that I can distribute (to students, for example) I need to anticipate the environment in which they will be using it. The vast majority of Linux distributions out there use a fork of BLT which calls itself "v 2.5.3" - just because there is a convenient Debian/Ubuntu package of it that is installed by default by apt install blt. ActiveTCL which dominates the Windows world has dropped support for BLT altogether, although one can still find a v.2.4.7z that will install and run there. We tend to recommend to Windows users undroidwish/vanillawish which has BLT 2.4.7z built in, and this also works under Android and MacOS (androwish.org).

            And I keep hoping to return all the "strays" back to this mother project. Maybe when the official version 3.0 is released , it will be picked up by the Debian/Ubuntu maintainers. Not everyone will be willing to install from source.

            That is why I found myself needing to focus on robust code that runs under all flavours of BLT. As to the preference for making multiple vectors in a single command: that's just a desire for compactness and similarity with variable declarations in any other language, and a mild irritation at having to modify perfectly good code that's been running for years.

             
  • Edward Sternin

    Edward Sternin - 2022-07-06

    Very simple but useful things that are missing in v.2.x : [x min] and [x max]. This is difficult to overcome (my shortest version is x dup xx; xx sort; puts "$xx(0)" for min), and the best workaround I found is to use critcl:

    package require BLT
    namespace import ::blt::*
    package require critcl
    critcl::clibraries -lBLT
    critcl::ccode {
      #include <tcl.h>
      #include <blt.h>
      }
    critcl::cproc minValue { Tcl_Interp* ip Tcl_Obj* v } double {
      Blt_Vector *vp;
      Blt_GetVector(ip, Tcl_GetString(v), &vp);
      return vp->min;
      }
    critcl::cproc maxValue { Tcl_Interp* ip Tcl_Obj* v } double {
      Blt_Vector *vp;
      Blt_GetVector(ip, Tcl_GetString(v), &vp);
      return vp->max;
      }
    
    vector create x; x seq 5 0 -1
    puts "$x(:) is from [minValue x] to [maxValue x]"
    

    the Blt_Vector structure in C simply has the min/max within it, but in v.2.x access to them is not provided. The above will work under all versions, fast and with no memory overhead.

    Unless I missed something and @gah can correct me.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.